From ba09ef10b1e6ce2c67f88a24ff792e9d8a72b65b Mon Sep 17 00:00:00 2001 From: Divlo Date: Fri, 6 Jan 2023 21:18:19 +0100 Subject: [PATCH 1/5] feat: add generate:json-schemas script --- .gitignore | 1 + package.json | 1 + scripts/generate/generate-json-schemas.js | 78 +++++++++++++++++++ scripts/generate/run-generate-json-schemas.js | 14 ++++ scripts/setup/setup.js | 2 + 5 files changed, 96 insertions(+) create mode 100644 scripts/generate/generate-json-schemas.js create mode 100644 scripts/generate/run-generate-json-schemas.js diff --git a/.gitignore b/.gitignore index d4d8a4683..76827ed27 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ skills/**/memory/*.json core/data/models/*.nlp package.json.backup .python-version +schemas/**/*.json diff --git a/package.json b/package.json index 4f9cd59fb..e7767a825 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "prepare": "husky install", "generate:skills-endpoints": "ts-node scripts/generate/run-generate-skills-endpoints.js", "generate:http-api-key": "ts-node scripts/generate/run-generate-http-api-key.js", + "generate:json-schemas": "ts-node scripts/generate/run-generate-json-schemas.js", "build": "npm run build:app && npm run build:server", "build:app": "cross-env LEON_NODE_ENV=production ts-node scripts/app/run-build-app.js", "build:server": "npm run delete-dist:server && npm run train && npm run generate:skills-endpoints && tsc && resolve-tspaths && shx rm -rf server/dist/core server/dist/package.json && shx mv -f server/dist/server/src/* server/dist && shx rm -rf server/dist/server && shx mkdir -p server/dist/tmp", diff --git a/scripts/generate/generate-json-schemas.js b/scripts/generate/generate-json-schemas.js new file mode 100644 index 000000000..6bd0a1db3 --- /dev/null +++ b/scripts/generate/generate-json-schemas.js @@ -0,0 +1,78 @@ +import fs from 'node:fs' +import path from 'node:path' + +import { LogHelper } from '@/helpers/log-helper' +import { + domainSchemaObject, + skillSchemaObject, + skillConfigSchemaObject +} from '@/schemas/skill-schemas' +import { + globalEntitySchemaObject, + globalResolverSchemaObject, + globalAnswersSchemaObject +} from '@/schemas/global-data-schemas' +import { + amazonVoiceConfiguration, + googleCloudVoiceConfiguration, + watsonVoiceConfiguration +} from '@/schemas/voice-config-schemas' + +/** + * Generate JSON schemas + * @param {string} categoryName + * @param {Map} schemas + */ +export const generateSchemas = async (categoryName, schemas) => { + const categorySchemasPath = path.join(process.cwd(), 'schemas', categoryName) + await fs.promises.mkdir(categorySchemasPath, { recursive: true }) + for (const [schemaName, schemaObject] of schemas.entries()) { + const schemaPath = path.join(categorySchemasPath, `${schemaName}.json`) + await fs.promises.writeFile( + schemaPath, + JSON.stringify( + { + $schema: 'https://json-schema.org/draft-07/schema', + ...schemaObject + }, + null, + 2 + ) + ) + } +} + +export default async () => { + LogHelper.info('Generating the JSON schemas...') + await Promise.all([ + generateSchemas( + 'global-data', + new Map([ + ['global-entity', globalEntitySchemaObject], + ['global-resolver', globalResolverSchemaObject], + ['global-answers', globalAnswersSchemaObject] + ]) + ), + generateSchemas( + 'skill-schemas', + new Map([ + ['domain', domainSchemaObject], + ['skill', skillSchemaObject], + ['skill-config', skillConfigSchemaObject] + ]) + ), + generateSchemas( + 'voice-config-schemas', + new Map([ + ['amazon', amazonVoiceConfiguration], + [ + 'google-cloud', + googleCloudVoiceConfiguration + ], + ['watson-stt', watsonVoiceConfiguration], + ['watson-tts', watsonVoiceConfiguration] + ]) + ) + ]) + LogHelper.success('JSON schemas generated') +} diff --git a/scripts/generate/run-generate-json-schemas.js b/scripts/generate/run-generate-json-schemas.js new file mode 100644 index 000000000..2c96c50ae --- /dev/null +++ b/scripts/generate/run-generate-json-schemas.js @@ -0,0 +1,14 @@ +import { LogHelper } from '@/helpers/log-helper' + +import generateJsonSchemas from './generate-json-schemas' + +/** + * Execute the generating JSON schemas script + */ +;(async () => { + try { + await generateJsonSchemas() + } catch (error) { + LogHelper.error(`Failed to generate the json schemas: ${error}`) + } +})() diff --git a/scripts/setup/setup.js b/scripts/setup/setup.js index fe26b1bf3..5918c4218 100644 --- a/scripts/setup/setup.js +++ b/scripts/setup/setup.js @@ -3,6 +3,7 @@ import { LogHelper } from '@/helpers/log-helper' import train from '../train/train' import generateHttpApiKey from '../generate/generate-http-api-key' +import generateJsonSchemas from '../generate/generate-json-schemas' import setupDotenv from './setup-dotenv' import setupCore from './setup-core' @@ -22,6 +23,7 @@ import setupPythonBinaries from './setup-python-binaries' LoaderHelper.stop() await setupPythonBinaries() await generateHttpApiKey() + await generateJsonSchemas() LoaderHelper.start() await train() From 5d866664b21de1c9e01910751e8228ad8f6cabfc Mon Sep 17 00:00:00 2001 From: Divlo Date: Fri, 6 Jan 2023 21:18:27 +0100 Subject: [PATCH 2/5] fix(server): remove additionalProperties in schemas to allow $schema property --- server/src/schemas/global-data-schemas.ts | 9 +++------ server/src/schemas/skill-schemas.ts | 9 +++------ server/src/schemas/voice-config-schemas.ts | 9 +++------ 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/server/src/schemas/global-data-schemas.ts b/server/src/schemas/global-data-schemas.ts index 0cf35d989..3c226429b 100644 --- a/server/src/schemas/global-data-schemas.ts +++ b/server/src/schemas/global-data-schemas.ts @@ -16,8 +16,7 @@ export const globalEntitySchemaObject = Type.Strict( { additionalProperties: false } ) ) - }, - { additionalProperties: false } + } ) ) export const globalResolverSchemaObject = Type.Strict( @@ -34,8 +33,7 @@ export const globalResolverSchemaObject = Type.Strict( { additionalProperties: false } ) ) - }, - { additionalProperties: false } + } ) ) export const globalAnswersSchemaObject = Type.Strict( @@ -48,8 +46,7 @@ export const globalAnswersSchemaObject = Type.Strict( Type.Array(Type.String()) ]) ) - }, - { additionalProperties: false } + } ) ) diff --git a/server/src/schemas/skill-schemas.ts b/server/src/schemas/skill-schemas.ts index 863e881de..565bd1d14 100644 --- a/server/src/schemas/skill-schemas.ts +++ b/server/src/schemas/skill-schemas.ts @@ -79,8 +79,7 @@ export const domainSchemaObject = Type.Strict( Type.Object( { name: Type.String({ minLength: 1 }) - }, - { additionalProperties: false } + } ) ) export const skillSchemaObject = Type.Strict( @@ -102,8 +101,7 @@ export const skillSchemaObject = Type.Strict( }, { additionalProperties: false } ) - }, - { additionalProperties: false } + } ) ) export const skillConfigSchemaObject = Type.Strict( @@ -186,8 +184,7 @@ export const skillConfigSchemaObject = Type.Strict( ) ) ) - }, - { additionalProperties: false } + } ) ) diff --git a/server/src/schemas/voice-config-schemas.ts b/server/src/schemas/voice-config-schemas.ts index 0caf9154e..489e16852 100644 --- a/server/src/schemas/voice-config-schemas.ts +++ b/server/src/schemas/voice-config-schemas.ts @@ -9,8 +9,7 @@ export const amazonVoiceConfiguration = Type.Strict( secretAccessKey: Type.String() }), region: Type.String() - }, - { additionalProperties: false } + } ) ) export const googleCloudVoiceConfiguration = Type.Strict( @@ -26,8 +25,7 @@ export const googleCloudVoiceConfiguration = Type.Strict( token_uri: Type.String({ format: 'uri' }), auth_provider_x509_cert_url: Type.String({ format: 'uri' }), client_x509_cert_url: Type.String({ format: 'uri' }) - }, - { additionalProperties: false } + } ) ) export const watsonVoiceConfiguration = Type.Strict( @@ -35,8 +33,7 @@ export const watsonVoiceConfiguration = Type.Strict( { apikey: Type.String(), url: Type.String({ format: 'uri' }) - }, - { additionalProperties: false } + } ) ) From 609fb676e4e220cf9bf40af39e6fd836017b4511 Mon Sep 17 00:00:00 2001 From: Divlo Date: Fri, 6 Jan 2023 21:48:14 +0100 Subject: [PATCH 3/5] feat(server): pre-check validate $schema property --- server/src/pre-check.ts | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/server/src/pre-check.ts b/server/src/pre-check.ts index 76e107246..e6c0b3d94 100644 --- a/server/src/pre-check.ts +++ b/server/src/pre-check.ts @@ -37,14 +37,24 @@ interface ObjectUnknown { } const validateSchema = ( + schemaName: string, schema: ObjectUnknown, contentToValidate: ObjectUnknown, customErrorMesage: string ): void => { + const schemaFile = `${schemaName}.json` const validate = ajv.compile(schema) - const isValid = validate(contentToValidate) + const isValidSchemaKey = + typeof contentToValidate['$schema'] === 'string' && + contentToValidate['$schema'].endsWith(schemaFile) + const isValid = validate(contentToValidate) && isValidSchemaKey if (!isValid) { LogHelper.error(customErrorMesage) + if (!isValidSchemaKey) { + LogHelper.error( + `The schema key "$schema" is not valid. Expected "${schemaName}", but got "${contentToValidate['$schema']}".` + ) + } const errors = new AggregateAjvError(validate.errors ?? []) for (const error of errors) { LogHelper.error(error.message) @@ -88,6 +98,7 @@ const GLOBAL_DATA_SCHEMAS = { ) const [configName] = file.split('.') as [keyof typeof VOICE_CONFIG_SCHEMAS] validateSchema( + `voice-config-schemas/${configName}`, VOICE_CONFIG_SCHEMAS[configName], config, `The voice configuration schema "${voiceConfigPath}" is not valid:` @@ -116,6 +127,7 @@ const GLOBAL_DATA_SCHEMAS = { await fs.promises.readFile(globalEntityPath, 'utf8') ) validateSchema( + 'global-data/global-entity', globalEntitySchemaObject, globalEntity, `The global entity schema "${globalEntityPath}" is not valid:` @@ -136,6 +148,7 @@ const GLOBAL_DATA_SCHEMAS = { await fs.promises.readFile(globalResolverPath, 'utf8') ) validateSchema( + 'global-data/global-resolver', globalResolverSchemaObject, globalResolver, `The global resolver schema "${globalResolverPath}" is not valid:` @@ -147,12 +160,10 @@ const GLOBAL_DATA_SCHEMAS = { */ const globalAnswersPath = path.join(GLOBAL_DATA_PATH, lang, 'answers.json') const answers: GlobalAnswers = JSON.parse( - await fs.promises.readFile( - globalAnswersPath, - 'utf8' - ) + await fs.promises.readFile(globalAnswersPath, 'utf8') ) validateSchema( + 'global-data/global-answers', GLOBAL_DATA_SCHEMAS.answers, answers, `The global answers schema "${globalAnswersPath}" is not valid:` @@ -176,6 +187,7 @@ const GLOBAL_DATA_SCHEMAS = { await fs.promises.readFile(pathToDomain, 'utf8') ) validateSchema( + 'skill-schemas/domain', domainSchemaObject, domainObject, `The domain schema "${pathToDomain}" is not valid:` @@ -195,6 +207,7 @@ const GLOBAL_DATA_SCHEMAS = { await fs.promises.readFile(pathToSkill, 'utf8') ) validateSchema( + 'skill-schemas/skill', skillSchemaObject, skillObject, `The skill schema "${pathToSkill}" is not valid:` @@ -214,6 +227,7 @@ const GLOBAL_DATA_SCHEMAS = { await fs.promises.readFile(skillConfigPath, 'utf8') ) validateSchema( + 'skill-schemas/skill-config', skillConfigSchemaObject, skillConfig, `The skill config schema "${skillConfigPath}" is not valid:` From 248dbb84f00c9f229741ece9e782707352b91cc5 Mon Sep 17 00:00:00 2001 From: Divlo Date: Fri, 6 Jan 2023 21:48:35 +0100 Subject: [PATCH 4/5] chore: add $schema property to all JSON files --- core/config/voice/amazon.sample.json | 1 + core/config/voice/google-cloud.sample.json | 1 + core/config/voice/watson-stt.sample.json | 1 + core/config/voice/watson-tts.sample.json | 1 + core/data/en/answers.json | 1 + core/data/en/global-entities/color.json | 1 + core/data/en/global-entities/level.json | 1 + core/data/en/global-entities/partner_assistant.json | 1 + core/data/en/global-resolvers/affirmation_denial.json | 1 + core/data/fr/answers.json | 1 + core/data/fr/global-entities/color.json | 1 + core/data/fr/global-entities/level.json | 1 + core/data/fr/global-entities/partner_assistant.json | 1 + core/data/fr/global-resolvers/affirmation_denial.json | 1 + skills/business_finance/domain.json | 1 + skills/food_drink/domain.json | 1 + skills/games/akinator/config/en.json | 1 + skills/games/akinator/skill.json | 1 + skills/games/domain.json | 1 + skills/games/guess_the_number/config/en.json | 1 + skills/games/guess_the_number/skill.json | 1 + skills/games/rochambeau/config/en.json | 1 + skills/games/rochambeau/skill.json | 1 + skills/health_fitness/domain.json | 1 + skills/knowledge_education/domain.json | 1 + skills/leon/color/config/en.json | 1 + skills/leon/color/skill.json | 1 + skills/leon/domain.json | 1 + skills/leon/good_bye/config/en.json | 1 + skills/leon/good_bye/config/fr.json | 1 + skills/leon/good_bye/skill.json | 1 + skills/leon/greeting/config/en.json | 1 + skills/leon/greeting/config/fr.json | 1 + skills/leon/greeting/skill.json | 1 + skills/leon/introduction/config/en.json | 1 + skills/leon/introduction/config/fr.json | 1 + skills/leon/introduction/skill.json | 1 + skills/leon/joke/config/en.json | 1 + skills/leon/joke/config/fr.json | 1 + skills/leon/joke/skill.json | 1 + skills/leon/meaning_of_life/config/en.json | 1 + skills/leon/meaning_of_life/config/fr.json | 1 + skills/leon/meaning_of_life/skill.json | 1 + skills/leon/partner_assistant/config/en.json | 1 + skills/leon/partner_assistant/config/fr.json | 1 + skills/leon/partner_assistant/skill.json | 1 + skills/leon/random_number/config/en.json | 1 + skills/leon/random_number/config/fr.json | 1 + skills/leon/random_number/skill.json | 1 + skills/leon/welcome/config/en.json | 1 + skills/leon/welcome/config/fr.json | 1 + skills/leon/welcome/skill.json | 1 + skills/movies_tv/domain.json | 1 + skills/music_audio/domain.json | 1 + skills/news/domain.json | 1 + skills/news/github_trends/config/en.json | 1 + skills/news/github_trends/config/fr.json | 1 + skills/news/github_trends/skill.json | 1 + skills/news/product_hunt_trends/config/en.json | 1 + skills/news/product_hunt_trends/config/fr.json | 1 + skills/news/product_hunt_trends/skill.json | 1 + skills/productivity/domain.json | 1 + skills/productivity/todo_list/config/en.json | 1 + skills/productivity/todo_list/config/fr.json | 1 + skills/productivity/todo_list/skill.json | 1 + skills/shopping/domain.json | 1 + skills/smart_home/domain.json | 1 + skills/social_communication/domain.json | 1 + skills/social_communication/mbti/config/en.json | 1 + skills/social_communication/mbti/skill.json | 3 ++- skills/sport/domain.json | 1 + skills/travel_transportation/domain.json | 1 + skills/unknown/domain.json | 1 + skills/utilities/domain.json | 1 + skills/utilities/have_i_been_pwned/config/en.json | 1 + skills/utilities/have_i_been_pwned/config/fr.json | 1 + skills/utilities/have_i_been_pwned/skill.json | 1 + skills/utilities/is_it_down/config/en.json | 1 + skills/utilities/is_it_down/config/fr.json | 1 + skills/utilities/is_it_down/skill.json | 1 + skills/utilities/speed_test/config/en.json | 1 + skills/utilities/speed_test/config/fr.json | 1 + skills/utilities/speed_test/skill.json | 1 + skills/utilities/youtube_downloader/config/en.json | 1 + skills/utilities/youtube_downloader/config/fr.json | 1 + skills/utilities/youtube_downloader/skill.json | 1 + skills/weather/domain.json | 1 + 87 files changed, 88 insertions(+), 1 deletion(-) diff --git a/core/config/voice/amazon.sample.json b/core/config/voice/amazon.sample.json index 5b01fccf6..d3d671f09 100644 --- a/core/config/voice/amazon.sample.json +++ b/core/config/voice/amazon.sample.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/voice-config-schemas/amazon.json", "credentials": { "accessKeyId": "", "secretAccessKey": "" diff --git a/core/config/voice/google-cloud.sample.json b/core/config/voice/google-cloud.sample.json index 54245f2e8..31a79d848 100644 --- a/core/config/voice/google-cloud.sample.json +++ b/core/config/voice/google-cloud.sample.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/voice-config-schemas/google-cloud.json", "type": "service_account", "project_id": "", "private_key_id": "", diff --git a/core/config/voice/watson-stt.sample.json b/core/config/voice/watson-stt.sample.json index 562bf08d6..030cd0279 100644 --- a/core/config/voice/watson-stt.sample.json +++ b/core/config/voice/watson-stt.sample.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/voice-config-schemas/watson-stt.json", "apikey": "", "url": "https://stream.watsonplatform.net/speech-to-text/api" } diff --git a/core/config/voice/watson-tts.sample.json b/core/config/voice/watson-tts.sample.json index 69d736c71..c7dfe598f 100644 --- a/core/config/voice/watson-tts.sample.json +++ b/core/config/voice/watson-tts.sample.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/voice-config-schemas/watson-tts.json", "apikey": "", "url": "https://stream.watsonplatform.net/text-to-speech/api" } diff --git a/core/data/en/answers.json b/core/data/en/answers.json index 9897d1f97..e589344af 100644 --- a/core/data/en/answers.json +++ b/core/data/en/answers.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/global-data/global-answers.json", "answers": { "success": {}, "errors": { diff --git a/core/data/en/global-entities/color.json b/core/data/en/global-entities/color.json index 3506a090c..1a98fc666 100644 --- a/core/data/en/global-entities/color.json +++ b/core/data/en/global-entities/color.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "red": { "synonyms": ["red"], diff --git a/core/data/en/global-entities/level.json b/core/data/en/global-entities/level.json index 1ddce34b1..cdc0cdcf0 100644 --- a/core/data/en/global-entities/level.json +++ b/core/data/en/global-entities/level.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "LOW": { "synonyms": ["low"] diff --git a/core/data/en/global-entities/partner_assistant.json b/core/data/en/global-entities/partner_assistant.json index 9ef851086..ce43a5d4f 100644 --- a/core/data/en/global-entities/partner_assistant.json +++ b/core/data/en/global-entities/partner_assistant.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "Alexa": { "synonyms": ["Alexa"], diff --git a/core/data/en/global-resolvers/affirmation_denial.json b/core/data/en/global-resolvers/affirmation_denial.json index 95b5c6d58..fe22cb9f0 100644 --- a/core/data/en/global-resolvers/affirmation_denial.json +++ b/core/data/en/global-resolvers/affirmation_denial.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-resolver.json", "name": "affirmation_denial", "intents": { "affirmation": { diff --git a/core/data/fr/answers.json b/core/data/fr/answers.json index 76e763859..fab49086f 100644 --- a/core/data/fr/answers.json +++ b/core/data/fr/answers.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/global-data/global-answers.json", "answers": { "success": {}, "errors": { diff --git a/core/data/fr/global-entities/color.json b/core/data/fr/global-entities/color.json index 403929f12..af415bdb0 100644 --- a/core/data/fr/global-entities/color.json +++ b/core/data/fr/global-entities/color.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "rouge": { "synonyms": ["rouge"], diff --git a/core/data/fr/global-entities/level.json b/core/data/fr/global-entities/level.json index 5509983f5..da85e3aa9 100644 --- a/core/data/fr/global-entities/level.json +++ b/core/data/fr/global-entities/level.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "bas": { "synonyms": ["bas", "basse"], diff --git a/core/data/fr/global-entities/partner_assistant.json b/core/data/fr/global-entities/partner_assistant.json index 52ee59326..75a1f2114 100644 --- a/core/data/fr/global-entities/partner_assistant.json +++ b/core/data/fr/global-entities/partner_assistant.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-entity.json", "options": { "Alexa": { "synonyms": ["Alexa"], diff --git a/core/data/fr/global-resolvers/affirmation_denial.json b/core/data/fr/global-resolvers/affirmation_denial.json index bb044bd4d..ddd9afb83 100644 --- a/core/data/fr/global-resolvers/affirmation_denial.json +++ b/core/data/fr/global-resolvers/affirmation_denial.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/global-data/global-resolver.json", "name": "affirmation_denial", "intents": { "affirmation": { diff --git a/skills/business_finance/domain.json b/skills/business_finance/domain.json index 3d74169af..adfce0494 100644 --- a/skills/business_finance/domain.json +++ b/skills/business_finance/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Business & Finance" } diff --git a/skills/food_drink/domain.json b/skills/food_drink/domain.json index 476e186d4..e8c135094 100644 --- a/skills/food_drink/domain.json +++ b/skills/food_drink/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Food & Drink" } diff --git a/skills/games/akinator/config/en.json b/skills/games/akinator/config/en.json index d2a8659b8..5939b1b3f 100644 --- a/skills/games/akinator/config/en.json +++ b/skills/games/akinator/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "choose_thematic": { "type": "dialog", diff --git a/skills/games/akinator/skill.json b/skills/games/akinator/skill.json index da8c0a728..54ee4ad12 100644 --- a/skills/games/akinator/skill.json +++ b/skills/games/akinator/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Akinator", "bridge": "python", "version": "1.0.0", diff --git a/skills/games/domain.json b/skills/games/domain.json index 8cd69b9a7..d2ddfcaf3 100644 --- a/skills/games/domain.json +++ b/skills/games/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Games" } diff --git a/skills/games/guess_the_number/config/en.json b/skills/games/guess_the_number/config/en.json index 6dac2ee76..d64a177df 100644 --- a/skills/games/guess_the_number/config/en.json +++ b/skills/games/guess_the_number/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "setup": { "type": "logic", diff --git a/skills/games/guess_the_number/skill.json b/skills/games/guess_the_number/skill.json index 0c4322af1..baff373f9 100644 --- a/skills/games/guess_the_number/skill.json +++ b/skills/games/guess_the_number/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Guess the Number", "bridge": "python", "version": "1.0.0", diff --git a/skills/games/rochambeau/config/en.json b/skills/games/rochambeau/config/en.json index ddc80b002..9ed16f2b4 100644 --- a/skills/games/rochambeau/config/en.json +++ b/skills/games/rochambeau/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "start": { "type": "dialog", diff --git a/skills/games/rochambeau/skill.json b/skills/games/rochambeau/skill.json index d828dd911..0a56c497e 100644 --- a/skills/games/rochambeau/skill.json +++ b/skills/games/rochambeau/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Rochambeau", "bridge": "python", "version": "1.0.0", diff --git a/skills/health_fitness/domain.json b/skills/health_fitness/domain.json index a7098be66..333cf3599 100644 --- a/skills/health_fitness/domain.json +++ b/skills/health_fitness/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Health & Fitness" } diff --git a/skills/knowledge_education/domain.json b/skills/knowledge_education/domain.json index e48727714..31a59bb4b 100644 --- a/skills/knowledge_education/domain.json +++ b/skills/knowledge_education/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Knowledge & Education" } diff --git a/skills/leon/color/config/en.json b/skills/leon/color/config/en.json index e2448bd12..2a5e27425 100644 --- a/skills/leon/color/config/en.json +++ b/skills/leon/color/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "variables": { "blue_leon": "#1C75DB", "pink_leon": "#ED297A" diff --git a/skills/leon/color/skill.json b/skills/leon/color/skill.json index 41ba26587..fa7e38790 100644 --- a/skills/leon/color/skill.json +++ b/skills/leon/color/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Color", "bridge": null, "version": "1.0.0", diff --git a/skills/leon/domain.json b/skills/leon/domain.json index ad1c2d772..fa0a163d7 100644 --- a/skills/leon/domain.json +++ b/skills/leon/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Leon" } diff --git a/skills/leon/good_bye/config/en.json b/skills/leon/good_bye/config/en.json index 6bf78e067..e0beadb6c 100644 --- a/skills/leon/good_bye/config/en.json +++ b/skills/leon/good_bye/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/good_bye/config/fr.json b/skills/leon/good_bye/config/fr.json index 8654cb2f4..debdd0493 100644 --- a/skills/leon/good_bye/config/fr.json +++ b/skills/leon/good_bye/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/good_bye/skill.json b/skills/leon/good_bye/skill.json index 183e3df0e..69ae61b15 100644 --- a/skills/leon/good_bye/skill.json +++ b/skills/leon/good_bye/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Good Bye", "bridge": null, "version": "1.0.0", diff --git a/skills/leon/greeting/config/en.json b/skills/leon/greeting/config/en.json index 5482a4ff4..dc1393153 100644 --- a/skills/leon/greeting/config/en.json +++ b/skills/leon/greeting/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/leon/greeting/config/fr.json b/skills/leon/greeting/config/fr.json index 5096d418e..61902519c 100644 --- a/skills/leon/greeting/config/fr.json +++ b/skills/leon/greeting/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/leon/greeting/skill.json b/skills/leon/greeting/skill.json index 2e572fab0..3ad83760d 100644 --- a/skills/leon/greeting/skill.json +++ b/skills/leon/greeting/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Greeting", "bridge": "python", "version": "1.0.0", diff --git a/skills/leon/introduction/config/en.json b/skills/leon/introduction/config/en.json index 4be7e859e..bdf74e3ab 100644 --- a/skills/leon/introduction/config/en.json +++ b/skills/leon/introduction/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "variables": { "leon_introduction_1": "I'm your daily personal assistant. I have been created by Louis. I'm very happy to serve you everyday.", "leon_introduction_2": "The question is, who are you? I'm kidding! I'm your daily personal assistant. Louis created me to make your life easier.", diff --git a/skills/leon/introduction/config/fr.json b/skills/leon/introduction/config/fr.json index 5096d418e..61902519c 100644 --- a/skills/leon/introduction/config/fr.json +++ b/skills/leon/introduction/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/leon/introduction/skill.json b/skills/leon/introduction/skill.json index f56d4421e..1e4d13b6b 100644 --- a/skills/leon/introduction/skill.json +++ b/skills/leon/introduction/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Introduction", "bridge": "python", "version": "1.0.0", diff --git a/skills/leon/joke/config/en.json b/skills/leon/joke/config/en.json index 2174e93f0..fff643def 100644 --- a/skills/leon/joke/config/en.json +++ b/skills/leon/joke/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/joke/config/fr.json b/skills/leon/joke/config/fr.json index b83bc93e0..7e81a802c 100644 --- a/skills/leon/joke/config/fr.json +++ b/skills/leon/joke/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/joke/skill.json b/skills/leon/joke/skill.json index 629c04e92..3ef2c6131 100644 --- a/skills/leon/joke/skill.json +++ b/skills/leon/joke/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Joke", "bridge": null, "version": "1.0.0", diff --git a/skills/leon/meaning_of_life/config/en.json b/skills/leon/meaning_of_life/config/en.json index 67ba2da5b..eda273d8e 100644 --- a/skills/leon/meaning_of_life/config/en.json +++ b/skills/leon/meaning_of_life/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/meaning_of_life/config/fr.json b/skills/leon/meaning_of_life/config/fr.json index a87079e3d..1479be412 100644 --- a/skills/leon/meaning_of_life/config/fr.json +++ b/skills/leon/meaning_of_life/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/meaning_of_life/skill.json b/skills/leon/meaning_of_life/skill.json index 0196ca458..d7cb6c545 100644 --- a/skills/leon/meaning_of_life/skill.json +++ b/skills/leon/meaning_of_life/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Meaning of Life", "bridge": null, "version": "1.0.0", diff --git a/skills/leon/partner_assistant/config/en.json b/skills/leon/partner_assistant/config/en.json index f8f22a9be..ac9f6b294 100644 --- a/skills/leon/partner_assistant/config/en.json +++ b/skills/leon/partner_assistant/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/partner_assistant/config/fr.json b/skills/leon/partner_assistant/config/fr.json index eab80845e..53ccbdd6c 100644 --- a/skills/leon/partner_assistant/config/fr.json +++ b/skills/leon/partner_assistant/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/partner_assistant/skill.json b/skills/leon/partner_assistant/skill.json index 69fa41b5a..ad2e2bf1a 100644 --- a/skills/leon/partner_assistant/skill.json +++ b/skills/leon/partner_assistant/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Partner Assistant", "bridge": null, "version": "1.0.0", diff --git a/skills/leon/random_number/config/en.json b/skills/leon/random_number/config/en.json index 79c91b804..19b42acdb 100644 --- a/skills/leon/random_number/config/en.json +++ b/skills/leon/random_number/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/leon/random_number/config/fr.json b/skills/leon/random_number/config/fr.json index 0e0bc97fc..40f54cea5 100644 --- a/skills/leon/random_number/config/fr.json +++ b/skills/leon/random_number/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/leon/random_number/skill.json b/skills/leon/random_number/skill.json index 32d9ab71c..a0f072777 100644 --- a/skills/leon/random_number/skill.json +++ b/skills/leon/random_number/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Random Number", "bridge": "python", "version": "1.0.0", diff --git a/skills/leon/welcome/config/en.json b/skills/leon/welcome/config/en.json index ee9b060e4..8e3af653d 100644 --- a/skills/leon/welcome/config/en.json +++ b/skills/leon/welcome/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/welcome/config/fr.json b/skills/leon/welcome/config/fr.json index 24d67a7a6..5288aaed1 100644 --- a/skills/leon/welcome/config/fr.json +++ b/skills/leon/welcome/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "dialog", diff --git a/skills/leon/welcome/skill.json b/skills/leon/welcome/skill.json index 4c0ce7646..55579b32e 100644 --- a/skills/leon/welcome/skill.json +++ b/skills/leon/welcome/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Welcome", "bridge": null, "version": "1.0.0", diff --git a/skills/movies_tv/domain.json b/skills/movies_tv/domain.json index 98d33a498..fd913670e 100644 --- a/skills/movies_tv/domain.json +++ b/skills/movies_tv/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Movies & TV" } diff --git a/skills/music_audio/domain.json b/skills/music_audio/domain.json index a59ee1471..18ccdfbff 100644 --- a/skills/music_audio/domain.json +++ b/skills/music_audio/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Music & Audio" } diff --git a/skills/news/domain.json b/skills/news/domain.json index 2bfef70dd..a33739380 100644 --- a/skills/news/domain.json +++ b/skills/news/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "News" } diff --git a/skills/news/github_trends/config/en.json b/skills/news/github_trends/config/en.json index b5352dcd3..638a53764 100644 --- a/skills/news/github_trends/config/en.json +++ b/skills/news/github_trends/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/news/github_trends/config/fr.json b/skills/news/github_trends/config/fr.json index 5332d4930..693ee818c 100644 --- a/skills/news/github_trends/config/fr.json +++ b/skills/news/github_trends/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/news/github_trends/skill.json b/skills/news/github_trends/skill.json index 552f9e046..3f7ea642e 100644 --- a/skills/news/github_trends/skill.json +++ b/skills/news/github_trends/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "GitHub Trends", "bridge": "python", "version": "1.0.0", diff --git a/skills/news/product_hunt_trends/config/en.json b/skills/news/product_hunt_trends/config/en.json index 9a059ad9d..05a8b205c 100644 --- a/skills/news/product_hunt_trends/config/en.json +++ b/skills/news/product_hunt_trends/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/news/product_hunt_trends/config/fr.json b/skills/news/product_hunt_trends/config/fr.json index 0b53cd9f3..8bcd82e42 100644 --- a/skills/news/product_hunt_trends/config/fr.json +++ b/skills/news/product_hunt_trends/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/news/product_hunt_trends/skill.json b/skills/news/product_hunt_trends/skill.json index 360672c71..ef80e2ed3 100644 --- a/skills/news/product_hunt_trends/skill.json +++ b/skills/news/product_hunt_trends/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Product Hunt Trends", "bridge": "python", "version": "1.0.0", diff --git a/skills/productivity/domain.json b/skills/productivity/domain.json index 88a2a1ce5..bfa5c6002 100644 --- a/skills/productivity/domain.json +++ b/skills/productivity/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Productivity" } diff --git a/skills/productivity/todo_list/config/en.json b/skills/productivity/todo_list/config/en.json index ab76c7a9b..801e670db 100644 --- a/skills/productivity/todo_list/config/en.json +++ b/skills/productivity/todo_list/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "create_list": { "type": "logic", diff --git a/skills/productivity/todo_list/config/fr.json b/skills/productivity/todo_list/config/fr.json index 7eac2c5c0..506d56fea 100644 --- a/skills/productivity/todo_list/config/fr.json +++ b/skills/productivity/todo_list/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "create_list": { "type": "logic", diff --git a/skills/productivity/todo_list/skill.json b/skills/productivity/todo_list/skill.json index 94e0a3a84..bc74ca125 100644 --- a/skills/productivity/todo_list/skill.json +++ b/skills/productivity/todo_list/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Todo List", "bridge": "python", "version": "1.0.0", diff --git a/skills/shopping/domain.json b/skills/shopping/domain.json index a422a476d..66486de31 100644 --- a/skills/shopping/domain.json +++ b/skills/shopping/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Shopping" } diff --git a/skills/smart_home/domain.json b/skills/smart_home/domain.json index f4f9006aa..6a0c560ec 100644 --- a/skills/smart_home/domain.json +++ b/skills/smart_home/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Smart Home" } diff --git a/skills/social_communication/domain.json b/skills/social_communication/domain.json index 115ba7f03..19e060c7f 100644 --- a/skills/social_communication/domain.json +++ b/skills/social_communication/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Social & Communication" } diff --git a/skills/social_communication/mbti/config/en.json b/skills/social_communication/mbti/config/en.json index fa8d5496a..5c2847f13 100644 --- a/skills/social_communication/mbti/config/en.json +++ b/skills/social_communication/mbti/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "setup": { "type": "logic", diff --git a/skills/social_communication/mbti/skill.json b/skills/social_communication/mbti/skill.json index bddec5400..37ffd96f6 100644 --- a/skills/social_communication/mbti/skill.json +++ b/skills/social_communication/mbti/skill.json @@ -1,5 +1,6 @@ { - "name": "MBTI (Myers–Briggs Type Indicator)", + "$schema": "../../../schemas/skill-schemas/skill.json", + "name": "MBTI (Myers-Briggs Type Indicator)", "bridge": "python", "version": "1.0.0", "description": "Questionnaire to define your MBTI personality type.", diff --git a/skills/sport/domain.json b/skills/sport/domain.json index 4d8e00a71..5f6000261 100644 --- a/skills/sport/domain.json +++ b/skills/sport/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Sport" } diff --git a/skills/travel_transportation/domain.json b/skills/travel_transportation/domain.json index 68536f489..7b0cc6535 100644 --- a/skills/travel_transportation/domain.json +++ b/skills/travel_transportation/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Travel & Transportation" } diff --git a/skills/unknown/domain.json b/skills/unknown/domain.json index 6b04d3241..d30c7d572 100644 --- a/skills/unknown/domain.json +++ b/skills/unknown/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Unknown" } diff --git a/skills/utilities/domain.json b/skills/utilities/domain.json index 6b743b073..75d89346c 100644 --- a/skills/utilities/domain.json +++ b/skills/utilities/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Utilities" } diff --git a/skills/utilities/have_i_been_pwned/config/en.json b/skills/utilities/have_i_been_pwned/config/en.json index 7ae2d5f3a..cd2ebc8cc 100644 --- a/skills/utilities/have_i_been_pwned/config/en.json +++ b/skills/utilities/have_i_been_pwned/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/have_i_been_pwned/config/fr.json b/skills/utilities/have_i_been_pwned/config/fr.json index 45ecf7324..df4dfe1fb 100644 --- a/skills/utilities/have_i_been_pwned/config/fr.json +++ b/skills/utilities/have_i_been_pwned/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/have_i_been_pwned/skill.json b/skills/utilities/have_i_been_pwned/skill.json index d330d9bd1..033333730 100644 --- a/skills/utilities/have_i_been_pwned/skill.json +++ b/skills/utilities/have_i_been_pwned/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Have I Been Pwned", "bridge": "python", "version": "1.0.0", diff --git a/skills/utilities/is_it_down/config/en.json b/skills/utilities/is_it_down/config/en.json index 2088fea4a..e3c44a378 100644 --- a/skills/utilities/is_it_down/config/en.json +++ b/skills/utilities/is_it_down/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/is_it_down/config/fr.json b/skills/utilities/is_it_down/config/fr.json index b88712504..a4d6ccd7d 100644 --- a/skills/utilities/is_it_down/config/fr.json +++ b/skills/utilities/is_it_down/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/is_it_down/skill.json b/skills/utilities/is_it_down/skill.json index fa3513245..6c8dcd9c2 100644 --- a/skills/utilities/is_it_down/skill.json +++ b/skills/utilities/is_it_down/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Is It Down", "bridge": "python", "version": "1.0.0", diff --git a/skills/utilities/speed_test/config/en.json b/skills/utilities/speed_test/config/en.json index afb2bb967..e67176185 100644 --- a/skills/utilities/speed_test/config/en.json +++ b/skills/utilities/speed_test/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/speed_test/config/fr.json b/skills/utilities/speed_test/config/fr.json index d50ba8a2d..06eea4573 100644 --- a/skills/utilities/speed_test/config/fr.json +++ b/skills/utilities/speed_test/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/speed_test/skill.json b/skills/utilities/speed_test/skill.json index c0cfb3d61..0dfe27e3e 100644 --- a/skills/utilities/speed_test/skill.json +++ b/skills/utilities/speed_test/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "Speed Test", "bridge": "python", "version": "1.0.0", diff --git a/skills/utilities/youtube_downloader/config/en.json b/skills/utilities/youtube_downloader/config/en.json index 80b939c18..cb4d20197 100644 --- a/skills/utilities/youtube_downloader/config/en.json +++ b/skills/utilities/youtube_downloader/config/en.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/youtube_downloader/config/fr.json b/skills/utilities/youtube_downloader/config/fr.json index 6601cf879..f202920f3 100644 --- a/skills/utilities/youtube_downloader/config/fr.json +++ b/skills/utilities/youtube_downloader/config/fr.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../schemas/skill-schemas/skill-config.json", "actions": { "run": { "type": "logic", diff --git a/skills/utilities/youtube_downloader/skill.json b/skills/utilities/youtube_downloader/skill.json index 4b8837885..4ea84f92a 100644 --- a/skills/utilities/youtube_downloader/skill.json +++ b/skills/utilities/youtube_downloader/skill.json @@ -1,4 +1,5 @@ { + "$schema": "../../../schemas/skill-schemas/skill.json", "name": "YouTube Downloader", "bridge": "python", "version": "1.0.0", diff --git a/skills/weather/domain.json b/skills/weather/domain.json index c61a9cb89..048cb7ab8 100644 --- a/skills/weather/domain.json +++ b/skills/weather/domain.json @@ -1,3 +1,4 @@ { + "$schema": "../../schemas/skill-schemas/domain.json", "name": "Weather" } From 31e44cde379704c0d38328462be02047898a0875 Mon Sep 17 00:00:00 2001 From: Divlo Date: Fri, 6 Jan 2023 22:20:55 +0100 Subject: [PATCH 5/5] fix(server): improve schemas by adding descriptions --- server/src/schemas/global-data-schemas.ts | 50 ++-- server/src/schemas/skill-schemas.ts | 267 ++++++++++++++-------- 2 files changed, 192 insertions(+), 125 deletions(-) diff --git a/server/src/schemas/global-data-schemas.ts b/server/src/schemas/global-data-schemas.ts index 3c226429b..e16ddd888 100644 --- a/server/src/schemas/global-data-schemas.ts +++ b/server/src/schemas/global-data-schemas.ts @@ -16,38 +16,38 @@ export const globalEntitySchemaObject = Type.Strict( { additionalProperties: false } ) ) + }, + { + description: + 'Global entities can hold data that can directly be reused in skills.' } ) ) export const globalResolverSchemaObject = Type.Strict( - Type.Object( - { - name: Type.String(), - intents: Type.Record( - Type.String(), - Type.Object( - { - utterance_samples: Type.Array(Type.String()), - value: Type.Unknown() - }, - { additionalProperties: false } - ) + Type.Object({ + name: Type.String(), + intents: Type.Record( + Type.String(), + Type.Object( + { + utterance_samples: Type.Array(Type.String()), + value: Type.Unknown() + }, + { additionalProperties: false } ) - } - ) + ) + }) ) export const globalAnswersSchemaObject = Type.Strict( - Type.Object( - { - answers: Type.Record( - Type.String(), - Type.Union([ - Type.Record(Type.String(), Type.String()), - Type.Array(Type.String()) - ]) - ) - } - ) + Type.Object({ + answers: Type.Record( + Type.String(), + Type.Union([ + Type.Record(Type.String(), Type.String()), + Type.Array(Type.String()) + ]) + ) + }) ) export type GlobalEntity = Static diff --git a/server/src/schemas/skill-schemas.ts b/server/src/schemas/skill-schemas.ts index 565bd1d14..db280294b 100644 --- a/server/src/schemas/skill-schemas.ts +++ b/server/src/schemas/skill-schemas.ts @@ -4,7 +4,15 @@ import { Type } from '@sinclair/typebox' import { globalResolverSchemaObject } from '@/schemas/global-data-schemas' const skillBridges = [Type.Literal('python'), Type.Null()] -const skillActionTypes = [Type.Literal('logic'), Type.Literal('dialog')] +const skillActionTypes = [ + Type.Literal('logic', { + description: 'It runs the business logic implemented in actions via code.' + }), + Type.Literal('dialog', { + description: + "Action that don't need code to run. Leon actually just answers without any business logic." + }) +] const skillDataTypes = [ Type.Literal('skill_resolver'), Type.Literal('global_resolver'), @@ -45,7 +53,11 @@ const skillCustomEntityTypes = [ ) ) }, - { additionalProperties: false } + { + additionalProperties: false, + description: + 'Trim: you can pick up a data from an utterance by clearly defining conditions (e.g: pick up what is after the last “with” word of the utterance).' + } ) ), Type.Array( @@ -55,7 +67,10 @@ const skillCustomEntityTypes = [ name: Type.String({ minLength: 1 }), regex: Type.String({ minLength: 1 }) }, - { additionalProperties: false } + { + additionalProperties: false, + description: 'Regex: you can create an entity based on a regex.' + } ) ), Type.Array( @@ -70,122 +85,174 @@ const skillCustomEntityTypes = [ }) ) }, - { additionalProperties: false } + { + additionalProperties: false, + description: + 'Enum: define a bag of words and synonyms that should match your new entity.' + } ) ) ] export const domainSchemaObject = Type.Strict( - Type.Object( - { - name: Type.String({ minLength: 1 }) - } - ) + Type.Object({ + name: Type.String({ minLength: 1, description: 'The name of the domain.' }) + }) ) export const skillSchemaObject = Type.Strict( - Type.Object( - { - name: Type.String({ minLength: 1 }), - bridge: Type.Union(skillBridges), - version: Type.String({ minLength: 1 }), - description: Type.String({ minLength: 1 }), - author: Type.Object( + Type.Object({ + name: Type.String({ minLength: 1, description: 'The name of the skill.' }), + bridge: Type.Union(skillBridges, { description: 'Bridge SDK.' }), + version: Type.String({ + minLength: 1, + description: 'Version following semver.' + }), + description: Type.String({ + minLength: 1, + description: 'This helps people understand what your skill does.' + }), + author: Type.Object( + { + name: Type.String({ minLength: 1, description: 'Name of the author.' }), + email: Type.Optional( + Type.String({ + minLength: 1, + maxLength: 254, + format: 'email', + description: 'Email address of the author.' + }) + ), + url: Type.Optional( + Type.String({ + minLength: 1, + maxLength: 255, + format: 'uri', + description: 'Website of the author.' + }) + ) + }, + { + additionalProperties: false, + description: + 'A person who has been involved in creating or maintaining this skill.' + } + ) + }) +) +export const skillConfigSchemaObject = Type.Strict( + Type.Object({ + variables: Type.Optional(Type.Record(Type.String(), Type.String())), + actions: Type.Record( + Type.String(), + Type.Object( { - name: Type.String({ minLength: 1 }), - email: Type.Optional( - Type.String({ minLength: 1, maxLength: 254, format: 'email' }) + type: Type.Union(skillActionTypes), + loop: Type.Optional( + Type.Object( + { + expected_item: Type.Object( + { + type: Type.Union(skillDataTypes), + name: Type.String() + }, + { description: 'An item can be a entity or a resolver.' } + ) + }, + { + additionalProperties: false, + description: + 'The action loop is a concept to keep Leon triggering the same skill action until the logic of the skill breaks the loop according to new utterances content.' + } + ) + ), + http_api: Type.Optional( + Type.Object( + { + entities: Type.Array( + Type.Object( + { + entity: Type.String(), + resolution: Type.Array(Type.String()) + }, + { additionalProperties: false } + ) + ) + }, + { additionalProperties: false } + ) + ), + utterance_samples: Type.Optional(Type.Array(Type.String())), + answers: Type.Optional(Type.Array(Type.String())), + unknown_answers: Type.Optional(Type.Array(Type.String())), + suggestions: Type.Optional( + Type.Array(Type.String(), { + description: + 'Suggestions are a simple way to suggest Leon owners what can be answered next.' + }) + ), + slots: Type.Optional( + Type.Array( + Type.Object( + { + name: Type.String(), + item: Type.Object( + { + type: Type.Union(skillDataTypes), + name: Type.String() + }, + { additionalProperties: false } + ), + questions: Type.Array(Type.String()), + suggestions: Type.Optional( + Type.Array(Type.String(), { + description: + 'Suggestions are a simple way to suggest Leon owners what can be answered next.' + }) + ) + }, + { + additionalProperties: false, + description: + 'A slot expects a type of data called "item", and makes use of questions to let Leon owners knows what data they need to provide.' + } + ), + { + description: + 'Depending on how skill developers wants to design their skill, they have the possibility to ask for more information before to get to the meat of the skill. In this way, Leon can gather these information to operate the skill in a complete manner. These information are called "slots".' + } + ) ), - url: Type.Optional( - Type.String({ minLength: 1, maxLength: 255, format: 'uri' }) + entities: Type.Optional(Type.Union(skillCustomEntityTypes)), + next_action: Type.Optional( + Type.String({ + description: + 'The next action property is useful when a skill needs to follow a specific order of actions, it helps to connect actions in a specific order to feed the context with data.' + }) ) }, { additionalProperties: false } ) - } - ) -) -export const skillConfigSchemaObject = Type.Strict( - Type.Object( - { - variables: Type.Optional(Type.Record(Type.String(), Type.String())), - actions: Type.Record( + ), + answers: Type.Optional( + Type.Record(Type.String(), Type.Array(Type.String())) + ), + entities: Type.Optional(Type.Record(Type.String(), Type.String())), + resolvers: Type.Optional( + Type.Record( Type.String(), Type.Object( { - type: Type.Union(skillActionTypes), - loop: Type.Optional( - Type.Object( - { - expected_item: Type.Object({ - type: Type.Union(skillDataTypes), - name: Type.String() - }) - }, - { additionalProperties: false } - ) - ), - http_api: Type.Optional( - Type.Object( - { - entities: Type.Array( - Type.Object( - { - entity: Type.String(), - resolution: Type.Array(Type.String()) - }, - { additionalProperties: false } - ) - ) - }, - { additionalProperties: false } - ) - ), - utterance_samples: Type.Optional(Type.Array(Type.String())), - answers: Type.Optional(Type.Array(Type.String())), - unknown_answers: Type.Optional(Type.Array(Type.String())), - suggestions: Type.Optional(Type.Array(Type.String())), - slots: Type.Optional( - Type.Array( - Type.Object( - { - name: Type.String(), - item: Type.Object( - { - type: Type.Union(skillDataTypes), - name: Type.String() - }, - { additionalProperties: false } - ), - questions: Type.Array(Type.String()), - suggestions: Type.Optional(Type.Array(Type.String())) - }, - { additionalProperties: false } - ) - ) - ), - entities: Type.Optional(Type.Union(skillCustomEntityTypes)), - next_action: Type.Optional(Type.String()) + intents: globalResolverSchemaObject.properties.intents }, { additionalProperties: false } - ) - ), - answers: Type.Optional( - Type.Record(Type.String(), Type.Array(Type.String())) - ), - entities: Type.Optional(Type.Record(Type.String(), Type.String())), - resolvers: Type.Optional( - Type.Record( - Type.String(), - Type.Object( - { - intents: globalResolverSchemaObject.properties.intents - }, - { additionalProperties: false } - ) - ) + ), + { + description: + 'You can see resolvers as utterance samples that are converted (resolved) to a value of your choice. They are very handy when skills expect specific utterances and then according to these utterances attribute a value that can be handled by the skill. If a skill action expects to receive a resolver, then Leon will convert the value for you and this value will be usable from the skill action code. Any value can be passed to resolvers which allow a large possibilities of usages.' + } ) - } - ) + ) + }) ) export type Domain = Static