From 5121f30d2d74a6909fa9bfc088a51d39f52f2ba0 Mon Sep 17 00:00:00 2001 From: samzong Date: Fri, 15 May 2026 15:53:05 +0800 Subject: [PATCH] fix(gateway): lazy compile protocol validators Signed-off-by: samzong --- src/gateway/protocol/index.test.ts | 70 ++++- src/gateway/protocol/index.ts | 399 +++++++++++++++++------------ 2 files changed, 302 insertions(+), 167 deletions(-) diff --git a/src/gateway/protocol/index.test.ts b/src/gateway/protocol/index.test.ts index 1eed33eec24..d19e928bf20 100644 --- a/src/gateway/protocol/index.test.ts +++ b/src/gateway/protocol/index.test.ts @@ -1,9 +1,12 @@ -import type { ErrorObject } from "ajv"; +import AjvPkg, { type ErrorObject } from "ajv"; import { describe, expect, it } from "vitest"; import { TALK_TEST_PROVIDER_ID } from "../../test-utils/talk-test-provider.js"; +import * as protocol from "./index.js"; import { formatValidationErrors, validateChatEvent, + validateCommandsListParams, + validateConnectParams, validateModelsListParams, validateNodeEventResult, validateNodePairRequestParams, @@ -35,6 +38,71 @@ const makeError = (overrides: Partial): ErrorObject => ({ ...overrides, }); +type CompileMethod = (schema: unknown, meta?: boolean) => unknown; +type ProtocolValidator = (value: unknown) => boolean; + +describe("lazy protocol validators", () => { + it("compiles on first use and reuses the compiled validator", () => { + const ajvPrototype = (AjvPkg as unknown as { prototype: { compile: CompileMethod } }).prototype; + const originalCompile = ajvPrototype.compile; + let compileCalls = 0; + + ajvPrototype.compile = function (this: unknown, schema: unknown, meta?: boolean) { + compileCalls += 1; + return originalCompile.call(this, schema, meta); + }; + + try { + expect(compileCalls).toBe(0); + expect(validateCommandsListParams({})).toBe(true); + expect(compileCalls).toBe(1); + expect(validateCommandsListParams({ includeArgs: true })).toBe(true); + expect(compileCalls).toBe(1); + } finally { + ajvPrototype.compile = originalCompile; + } + }); + + it("keeps validation errors readable on the exported validator", () => { + expect(validateConnectParams({})).toBe(false); + expect(formatValidationErrors(validateConnectParams.errors)).toContain("must have required"); + + expect( + validateConnectParams({ + minProtocol: 1, + maxProtocol: 1, + client: { + id: "test", + version: "1.0.0", + platform: "test", + mode: "test", + }, + }), + ).toBe(true); + expect(validateConnectParams.errors).toBeNull(); + }); + + it("can still compile every exported protocol validator", () => { + const failures: string[] = []; + const validators: Array<[string, ProtocolValidator]> = []; + for (const [name, value] of Object.entries(protocol)) { + if (name.startsWith("validate") && typeof value === "function") { + validators.push([name, value as ProtocolValidator]); + } + } + + expect(validators.length).toBeGreaterThan(150); + for (const [name, validate] of validators) { + try { + validate(undefined); + } catch (err) { + failures.push(`${name}: ${err instanceof Error ? err.message : String(err)}`); + } + } + expect(failures).toEqual([]); + }); +}); + describe("formatValidationErrors", () => { it("returns unknown validation error when missing errors", () => { expect(formatValidationErrors(undefined)).toBe("unknown validation error"); diff --git a/src/gateway/protocol/index.ts b/src/gateway/protocol/index.ts index ce6d23a9daa..64f0b77fa41 100644 --- a/src/gateway/protocol/index.ts +++ b/src/gateway/protocol/index.ts @@ -1,4 +1,4 @@ -import AjvPkg, { type ErrorObject } from "ajv"; +import AjvPkg, { type AnySchema, type ErrorObject, type ValidateFunction } from "ajv"; import type { SessionsPatchResult } from "../session-utils.types.js"; import { type AgentEvent, @@ -418,332 +418,399 @@ import { WizardStepSchema, } from "./schema.js"; -const ajv = new (AjvPkg as unknown as new (opts?: object) => import("ajv").default)({ - allErrors: true, - strict: false, - removeAdditional: false, -}); +type AjvInstance = import("ajv").default; +type ValidationContext = Parameters[1]; -export const validateCommandsListParams = ajv.compile(CommandsListParamsSchema); -export const validateConnectParams = ajv.compile(ConnectParamsSchema); -export const validateRequestFrame = ajv.compile(RequestFrameSchema); -export const validateResponseFrame = ajv.compile(ResponseFrameSchema); -export const validateEventFrame = ajv.compile(EventFrameSchema); +const AjvCtor = AjvPkg as unknown as new (opts?: object) => AjvInstance; + +let ajv: AjvInstance | undefined; + +function getAjv() { + ajv ??= new AjvCtor({ + allErrors: true, + strict: false, + removeAdditional: false, + }); + return ajv; +} + +function lazyCompile(schema: AnySchema): ValidateFunction { + let compiled: ValidateFunction | undefined; + + const getCompiled = () => { + compiled ??= getAjv().compile(schema); + return compiled; + }; + + const validate = ((data: unknown, dataCxt?: ValidationContext) => { + const current = getCompiled(); + const valid = current(data, dataCxt); + validate.errors = current.errors; + validate.evaluated = current.evaluated; + return valid; + }) as ValidateFunction; + + Object.defineProperties(validate, { + errors: { + configurable: true, + enumerable: true, + get: () => compiled?.errors ?? null, + set: (errors: ErrorObject[] | null | undefined) => { + if (compiled) { + compiled.errors = errors ?? null; + } + }, + }, + evaluated: { + configurable: true, + enumerable: true, + get: () => compiled?.evaluated, + set: (evaluated: ValidateFunction["evaluated"]) => { + if (compiled) { + compiled.evaluated = evaluated; + } + }, + }, + schema: { + configurable: true, + enumerable: true, + get: () => compiled?.schema ?? schema, + }, + schemaEnv: { + configurable: true, + enumerable: true, + get: () => getCompiled().schemaEnv, + }, + source: { + configurable: true, + enumerable: true, + get: () => compiled?.source, + }, + }); + + return validate; +} + +export const validateCommandsListParams = lazyCompile(CommandsListParamsSchema); +export const validateConnectParams = lazyCompile(ConnectParamsSchema); +export const validateRequestFrame = lazyCompile(RequestFrameSchema); +export const validateResponseFrame = lazyCompile(ResponseFrameSchema); +export const validateEventFrame = lazyCompile(EventFrameSchema); export const validateMessageActionParams = - ajv.compile(MessageActionParamsSchema); -export const validateSendParams = ajv.compile(SendParamsSchema); -export const validatePollParams = ajv.compile(PollParamsSchema); -export const validateAgentParams = ajv.compile(AgentParamsSchema); + lazyCompile(MessageActionParamsSchema); +export const validateSendParams = lazyCompile(SendParamsSchema); +export const validatePollParams = lazyCompile(PollParamsSchema); +export const validateAgentParams = lazyCompile(AgentParamsSchema); export const validateAgentIdentityParams = - ajv.compile(AgentIdentityParamsSchema); -export const validateAgentWaitParams = ajv.compile(AgentWaitParamsSchema); -export const validateWakeParams = ajv.compile(WakeParamsSchema); -export const validateAgentsListParams = ajv.compile(AgentsListParamsSchema); -export const validateAgentsCreateParams = ajv.compile(AgentsCreateParamsSchema); -export const validateAgentsUpdateParams = ajv.compile(AgentsUpdateParamsSchema); -export const validateAgentsDeleteParams = ajv.compile(AgentsDeleteParamsSchema); -export const validateAgentsFilesListParams = ajv.compile( + lazyCompile(AgentIdentityParamsSchema); +export const validateAgentWaitParams = lazyCompile(AgentWaitParamsSchema); +export const validateWakeParams = lazyCompile(WakeParamsSchema); +export const validateAgentsListParams = lazyCompile(AgentsListParamsSchema); +export const validateAgentsCreateParams = lazyCompile(AgentsCreateParamsSchema); +export const validateAgentsUpdateParams = lazyCompile(AgentsUpdateParamsSchema); +export const validateAgentsDeleteParams = lazyCompile(AgentsDeleteParamsSchema); +export const validateAgentsFilesListParams = lazyCompile( AgentsFilesListParamsSchema, ); -export const validateAgentsFilesGetParams = ajv.compile( +export const validateAgentsFilesGetParams = lazyCompile( AgentsFilesGetParamsSchema, ); -export const validateAgentsFilesSetParams = ajv.compile( +export const validateAgentsFilesSetParams = lazyCompile( AgentsFilesSetParamsSchema, ); export const validateArtifactsListParams = - ajv.compile(ArtifactsListParamsSchema); -export const validateArtifactsGetParams = ajv.compile(ArtifactsGetParamsSchema); -export const validateArtifactsDownloadParams = ajv.compile( + lazyCompile(ArtifactsListParamsSchema); +export const validateArtifactsGetParams = lazyCompile(ArtifactsGetParamsSchema); +export const validateArtifactsDownloadParams = lazyCompile( ArtifactsDownloadParamsSchema, ); -export const validateNodePairRequestParams = ajv.compile( +export const validateNodePairRequestParams = lazyCompile( NodePairRequestParamsSchema, ); -export const validateNodePairListParams = ajv.compile(NodePairListParamsSchema); -export const validateNodePairApproveParams = ajv.compile( +export const validateNodePairListParams = lazyCompile(NodePairListParamsSchema); +export const validateNodePairApproveParams = lazyCompile( NodePairApproveParamsSchema, ); -export const validateNodePairRejectParams = ajv.compile( +export const validateNodePairRejectParams = lazyCompile( NodePairRejectParamsSchema, ); -export const validateNodePairRemoveParams = ajv.compile( +export const validateNodePairRemoveParams = lazyCompile( NodePairRemoveParamsSchema, ); -export const validateNodePairVerifyParams = ajv.compile( +export const validateNodePairVerifyParams = lazyCompile( NodePairVerifyParamsSchema, ); -export const validateNodeRenameParams = ajv.compile(NodeRenameParamsSchema); -export const validateNodeListParams = ajv.compile(NodeListParamsSchema); -export const validateEnvironmentsListParams = ajv.compile( +export const validateNodeRenameParams = lazyCompile(NodeRenameParamsSchema); +export const validateNodeListParams = lazyCompile(NodeListParamsSchema); +export const validateEnvironmentsListParams = lazyCompile( EnvironmentsListParamsSchema, ); -export const validateEnvironmentsStatusParams = ajv.compile( +export const validateEnvironmentsStatusParams = lazyCompile( EnvironmentsStatusParamsSchema, ); -export const validateNodePendingAckParams = ajv.compile( +export const validateNodePendingAckParams = lazyCompile( NodePendingAckParamsSchema, ); -export const validateNodeDescribeParams = ajv.compile(NodeDescribeParamsSchema); -export const validateNodeInvokeParams = ajv.compile(NodeInvokeParamsSchema); -export const validateNodeInvokeResultParams = ajv.compile( +export const validateNodeDescribeParams = lazyCompile(NodeDescribeParamsSchema); +export const validateNodeInvokeParams = lazyCompile(NodeInvokeParamsSchema); +export const validateNodeInvokeResultParams = lazyCompile( NodeInvokeResultParamsSchema, ); -export const validateNodeEventParams = ajv.compile(NodeEventParamsSchema); -export const validateNodeEventResult = ajv.compile(NodeEventResultSchema); -export const validateNodePresenceAlivePayload = ajv.compile( +export const validateNodeEventParams = lazyCompile(NodeEventParamsSchema); +export const validateNodeEventResult = lazyCompile(NodeEventResultSchema); +export const validateNodePresenceAlivePayload = lazyCompile( NodePresenceAlivePayloadSchema, ); -export const validateNodePendingDrainParams = ajv.compile( +export const validateNodePendingDrainParams = lazyCompile( NodePendingDrainParamsSchema, ); -export const validateNodePendingEnqueueParams = ajv.compile( +export const validateNodePendingEnqueueParams = lazyCompile( NodePendingEnqueueParamsSchema, ); -export const validatePushTestParams = ajv.compile(PushTestParamsSchema); -export const validateWebPushVapidPublicKeyParams = ajv.compile( +export const validatePushTestParams = lazyCompile(PushTestParamsSchema); +export const validateWebPushVapidPublicKeyParams = lazyCompile( WebPushVapidPublicKeyParamsSchema, ); -export const validateWebPushSubscribeParams = ajv.compile( +export const validateWebPushSubscribeParams = lazyCompile( WebPushSubscribeParamsSchema, ); -export const validateWebPushUnsubscribeParams = ajv.compile( +export const validateWebPushUnsubscribeParams = lazyCompile( WebPushUnsubscribeParamsSchema, ); -export const validateWebPushTestParams = ajv.compile(WebPushTestParamsSchema); -export const validateSecretsResolveParams = ajv.compile( +export const validateWebPushTestParams = lazyCompile(WebPushTestParamsSchema); +export const validateSecretsResolveParams = lazyCompile( SecretsResolveParamsSchema, ); -export const validateSecretsResolveResult = ajv.compile( +export const validateSecretsResolveResult = lazyCompile( SecretsResolveResultSchema, ); -export const validateSessionsListParams = ajv.compile(SessionsListParamsSchema); -export const validateSessionsCleanupParams = ajv.compile( +export const validateSessionsListParams = lazyCompile(SessionsListParamsSchema); +export const validateSessionsCleanupParams = lazyCompile( SessionsCleanupParamsSchema, ); -export const validateSessionsPreviewParams = ajv.compile( +export const validateSessionsPreviewParams = lazyCompile( SessionsPreviewParamsSchema, ); -export const validateSessionsDescribeParams = ajv.compile( +export const validateSessionsDescribeParams = lazyCompile( SessionsDescribeParamsSchema, ); -export const validateSessionsResolveParams = ajv.compile( +export const validateSessionsResolveParams = lazyCompile( SessionsResolveParamsSchema, ); -export const validateSessionsCreateParams = ajv.compile( +export const validateSessionsCreateParams = lazyCompile( SessionsCreateParamsSchema, ); -export const validateSessionsSendParams = ajv.compile(SessionsSendParamsSchema); -export const validateSessionsMessagesSubscribeParams = ajv.compile( +export const validateSessionsSendParams = lazyCompile(SessionsSendParamsSchema); +export const validateSessionsMessagesSubscribeParams = lazyCompile( SessionsMessagesSubscribeParamsSchema, ); export const validateSessionsMessagesUnsubscribeParams = - ajv.compile(SessionsMessagesUnsubscribeParamsSchema); + lazyCompile(SessionsMessagesUnsubscribeParamsSchema); export const validateSessionsAbortParams = - ajv.compile(SessionsAbortParamsSchema); + lazyCompile(SessionsAbortParamsSchema); export const validateSessionsPatchParams = - ajv.compile(SessionsPatchParamsSchema); -export const validateSessionsPluginPatchParams = ajv.compile( + lazyCompile(SessionsPatchParamsSchema); +export const validateSessionsPluginPatchParams = lazyCompile( SessionsPluginPatchParamsSchema, ); export const validateSessionsResetParams = - ajv.compile(SessionsResetParamsSchema); -export const validateSessionsDeleteParams = ajv.compile( + lazyCompile(SessionsResetParamsSchema); +export const validateSessionsDeleteParams = lazyCompile( SessionsDeleteParamsSchema, ); -export const validateSessionsCompactParams = ajv.compile( +export const validateSessionsCompactParams = lazyCompile( SessionsCompactParamsSchema, ); -export const validateSessionsCompactionListParams = ajv.compile( +export const validateSessionsCompactionListParams = lazyCompile( SessionsCompactionListParamsSchema, ); -export const validateSessionsCompactionGetParams = ajv.compile( +export const validateSessionsCompactionGetParams = lazyCompile( SessionsCompactionGetParamsSchema, ); -export const validateSessionsCompactionBranchParams = ajv.compile( +export const validateSessionsCompactionBranchParams = lazyCompile( SessionsCompactionBranchParamsSchema, ); -export const validateSessionsCompactionRestoreParams = ajv.compile( +export const validateSessionsCompactionRestoreParams = lazyCompile( SessionsCompactionRestoreParamsSchema, ); export const validateSessionsUsageParams = - ajv.compile(SessionsUsageParamsSchema); -export const validateTasksListParams = ajv.compile(TasksListParamsSchema); -export const validateTasksGetParams = ajv.compile(TasksGetParamsSchema); -export const validateTasksCancelParams = ajv.compile(TasksCancelParamsSchema); -export const validateConfigGetParams = ajv.compile(ConfigGetParamsSchema); -export const validateConfigSetParams = ajv.compile(ConfigSetParamsSchema); -export const validateConfigApplyParams = ajv.compile(ConfigApplyParamsSchema); -export const validateConfigPatchParams = ajv.compile(ConfigPatchParamsSchema); -export const validateConfigSchemaParams = ajv.compile(ConfigSchemaParamsSchema); -export const validateConfigSchemaLookupParams = ajv.compile( + lazyCompile(SessionsUsageParamsSchema); +export const validateTasksListParams = lazyCompile(TasksListParamsSchema); +export const validateTasksGetParams = lazyCompile(TasksGetParamsSchema); +export const validateTasksCancelParams = lazyCompile(TasksCancelParamsSchema); +export const validateConfigGetParams = lazyCompile(ConfigGetParamsSchema); +export const validateConfigSetParams = lazyCompile(ConfigSetParamsSchema); +export const validateConfigApplyParams = lazyCompile(ConfigApplyParamsSchema); +export const validateConfigPatchParams = lazyCompile(ConfigPatchParamsSchema); +export const validateConfigSchemaParams = lazyCompile(ConfigSchemaParamsSchema); +export const validateConfigSchemaLookupParams = lazyCompile( ConfigSchemaLookupParamsSchema, ); -export const validateConfigSchemaLookupResult = ajv.compile( +export const validateConfigSchemaLookupResult = lazyCompile( ConfigSchemaLookupResultSchema, ); -export const validateWizardStartParams = ajv.compile(WizardStartParamsSchema); -export const validateWizardNextParams = ajv.compile(WizardNextParamsSchema); -export const validateWizardCancelParams = ajv.compile(WizardCancelParamsSchema); -export const validateWizardStatusParams = ajv.compile(WizardStatusParamsSchema); -export const validateTalkModeParams = ajv.compile(TalkModeParamsSchema); -export const validateTalkEvent = ajv.compile(TalkEventSchema); -export const validateTalkCatalogParams = ajv.compile(TalkCatalogParamsSchema); -export const validateTalkCatalogResult = ajv.compile(TalkCatalogResultSchema); -export const validateTalkConfigParams = ajv.compile(TalkConfigParamsSchema); -export const validateTalkConfigResult = ajv.compile(TalkConfigResultSchema); -export const validateTalkClientCreateParams = ajv.compile( +export const validateWizardStartParams = lazyCompile(WizardStartParamsSchema); +export const validateWizardNextParams = lazyCompile(WizardNextParamsSchema); +export const validateWizardCancelParams = lazyCompile(WizardCancelParamsSchema); +export const validateWizardStatusParams = lazyCompile(WizardStatusParamsSchema); +export const validateTalkModeParams = lazyCompile(TalkModeParamsSchema); +export const validateTalkEvent = lazyCompile(TalkEventSchema); +export const validateTalkCatalogParams = lazyCompile(TalkCatalogParamsSchema); +export const validateTalkCatalogResult = lazyCompile(TalkCatalogResultSchema); +export const validateTalkConfigParams = lazyCompile(TalkConfigParamsSchema); +export const validateTalkConfigResult = lazyCompile(TalkConfigResultSchema); +export const validateTalkClientCreateParams = lazyCompile( TalkClientCreateParamsSchema, ); -export const validateTalkClientCreateResult = ajv.compile( +export const validateTalkClientCreateResult = lazyCompile( TalkClientCreateResultSchema, ); -export const validateTalkClientToolCallParams = ajv.compile( +export const validateTalkClientToolCallParams = lazyCompile( TalkClientToolCallParamsSchema, ); -export const validateTalkClientToolCallResult = ajv.compile( +export const validateTalkClientToolCallResult = lazyCompile( TalkClientToolCallResultSchema, ); -export const validateTalkSessionCreateParams = ajv.compile( +export const validateTalkSessionCreateParams = lazyCompile( TalkSessionCreateParamsSchema, ); -export const validateTalkSessionCreateResult = ajv.compile( +export const validateTalkSessionCreateResult = lazyCompile( TalkSessionCreateResultSchema, ); -export const validateTalkSessionJoinParams = ajv.compile( +export const validateTalkSessionJoinParams = lazyCompile( TalkSessionJoinParamsSchema, ); -export const validateTalkSessionJoinResult = ajv.compile( +export const validateTalkSessionJoinResult = lazyCompile( TalkSessionJoinResultSchema, ); -export const validateTalkSessionAppendAudioParams = ajv.compile( +export const validateTalkSessionAppendAudioParams = lazyCompile( TalkSessionAppendAudioParamsSchema, ); -export const validateTalkSessionTurnParams = ajv.compile( +export const validateTalkSessionTurnParams = lazyCompile( TalkSessionTurnParamsSchema, ); -export const validateTalkSessionCancelTurnParams = ajv.compile( +export const validateTalkSessionCancelTurnParams = lazyCompile( TalkSessionCancelTurnParamsSchema, ); -export const validateTalkSessionCancelOutputParams = ajv.compile( +export const validateTalkSessionCancelOutputParams = lazyCompile( TalkSessionCancelOutputParamsSchema, ); -export const validateTalkSessionTurnResult = ajv.compile( +export const validateTalkSessionTurnResult = lazyCompile( TalkSessionTurnResultSchema, ); export const validateTalkSessionSubmitToolResultParams = - ajv.compile(TalkSessionSubmitToolResultParamsSchema); -export const validateTalkSessionCloseParams = ajv.compile( + lazyCompile(TalkSessionSubmitToolResultParamsSchema); +export const validateTalkSessionCloseParams = lazyCompile( TalkSessionCloseParamsSchema, ); export const validateTalkSessionOkResult = - ajv.compile(TalkSessionOkResultSchema); -export const validateTalkSpeakParams = ajv.compile(TalkSpeakParamsSchema); -export const validateTalkSpeakResult = ajv.compile(TalkSpeakResultSchema); -export const validateChannelsStatusParams = ajv.compile( + lazyCompile(TalkSessionOkResultSchema); +export const validateTalkSpeakParams = lazyCompile(TalkSpeakParamsSchema); +export const validateTalkSpeakResult = lazyCompile(TalkSpeakResultSchema); +export const validateChannelsStatusParams = lazyCompile( ChannelsStatusParamsSchema, ); export const validateChannelsStartParams = - ajv.compile(ChannelsStartParamsSchema); -export const validateChannelsStopParams = ajv.compile(ChannelsStopParamsSchema); -export const validateChannelsLogoutParams = ajv.compile( + lazyCompile(ChannelsStartParamsSchema); +export const validateChannelsStopParams = lazyCompile(ChannelsStopParamsSchema); +export const validateChannelsLogoutParams = lazyCompile( ChannelsLogoutParamsSchema, ); -export const validateModelsListParams = ajv.compile(ModelsListParamsSchema); -export const validateSkillsStatusParams = ajv.compile(SkillsStatusParamsSchema); -export const validateToolsCatalogParams = ajv.compile(ToolsCatalogParamsSchema); -export const validateToolsEffectiveParams = ajv.compile( +export const validateModelsListParams = lazyCompile(ModelsListParamsSchema); +export const validateSkillsStatusParams = lazyCompile(SkillsStatusParamsSchema); +export const validateToolsCatalogParams = lazyCompile(ToolsCatalogParamsSchema); +export const validateToolsEffectiveParams = lazyCompile( ToolsEffectiveParamsSchema, ); -export const validateToolsInvokeParams = ajv.compile(ToolsInvokeParamsSchema); -export const validateSkillsBinsParams = ajv.compile(SkillsBinsParamsSchema); +export const validateToolsInvokeParams = lazyCompile(ToolsInvokeParamsSchema); +export const validateSkillsBinsParams = lazyCompile(SkillsBinsParamsSchema); export const validateSkillsInstallParams = - ajv.compile(SkillsInstallParamsSchema); -export const validateSkillsUploadBeginParams = ajv.compile( + lazyCompile(SkillsInstallParamsSchema); +export const validateSkillsUploadBeginParams = lazyCompile( SkillsUploadBeginParamsSchema, ); -export const validateSkillsUploadChunkParams = ajv.compile( +export const validateSkillsUploadChunkParams = lazyCompile( SkillsUploadChunkParamsSchema, ); -export const validateSkillsUploadCommitParams = ajv.compile( +export const validateSkillsUploadCommitParams = lazyCompile( SkillsUploadCommitParamsSchema, ); -export const validateSkillsUpdateParams = ajv.compile(SkillsUpdateParamsSchema); -export const validateSkillsSearchParams = ajv.compile(SkillsSearchParamsSchema); -export const validateSkillsDetailParams = ajv.compile(SkillsDetailParamsSchema); -export const validateCronListParams = ajv.compile(CronListParamsSchema); -export const validateCronStatusParams = ajv.compile(CronStatusParamsSchema); -export const validateCronGetParams = ajv.compile(CronGetParamsSchema); -export const validateCronAddParams = ajv.compile(CronAddParamsSchema); -export const validateCronUpdateParams = ajv.compile(CronUpdateParamsSchema); -export const validateCronRemoveParams = ajv.compile(CronRemoveParamsSchema); -export const validateCronRunParams = ajv.compile(CronRunParamsSchema); -export const validateCronRunsParams = ajv.compile(CronRunsParamsSchema); -export const validateDevicePairListParams = ajv.compile( +export const validateSkillsUpdateParams = lazyCompile(SkillsUpdateParamsSchema); +export const validateSkillsSearchParams = lazyCompile(SkillsSearchParamsSchema); +export const validateSkillsDetailParams = lazyCompile(SkillsDetailParamsSchema); +export const validateCronListParams = lazyCompile(CronListParamsSchema); +export const validateCronStatusParams = lazyCompile(CronStatusParamsSchema); +export const validateCronGetParams = lazyCompile(CronGetParamsSchema); +export const validateCronAddParams = lazyCompile(CronAddParamsSchema); +export const validateCronUpdateParams = lazyCompile(CronUpdateParamsSchema); +export const validateCronRemoveParams = lazyCompile(CronRemoveParamsSchema); +export const validateCronRunParams = lazyCompile(CronRunParamsSchema); +export const validateCronRunsParams = lazyCompile(CronRunsParamsSchema); +export const validateDevicePairListParams = lazyCompile( DevicePairListParamsSchema, ); -export const validateDevicePairApproveParams = ajv.compile( +export const validateDevicePairApproveParams = lazyCompile( DevicePairApproveParamsSchema, ); -export const validateDevicePairRejectParams = ajv.compile( +export const validateDevicePairRejectParams = lazyCompile( DevicePairRejectParamsSchema, ); -export const validateDevicePairRemoveParams = ajv.compile( +export const validateDevicePairRemoveParams = lazyCompile( DevicePairRemoveParamsSchema, ); -export const validateDeviceTokenRotateParams = ajv.compile( +export const validateDeviceTokenRotateParams = lazyCompile( DeviceTokenRotateParamsSchema, ); -export const validateDeviceTokenRevokeParams = ajv.compile( +export const validateDeviceTokenRevokeParams = lazyCompile( DeviceTokenRevokeParamsSchema, ); -export const validateExecApprovalsGetParams = ajv.compile( +export const validateExecApprovalsGetParams = lazyCompile( ExecApprovalsGetParamsSchema, ); -export const validateExecApprovalsSetParams = ajv.compile( +export const validateExecApprovalsSetParams = lazyCompile( ExecApprovalsSetParamsSchema, ); -export const validateExecApprovalGetParams = ajv.compile( +export const validateExecApprovalGetParams = lazyCompile( ExecApprovalGetParamsSchema, ); -export const validateExecApprovalRequestParams = ajv.compile( +export const validateExecApprovalRequestParams = lazyCompile( ExecApprovalRequestParamsSchema, ); -export const validateExecApprovalResolveParams = ajv.compile( +export const validateExecApprovalResolveParams = lazyCompile( ExecApprovalResolveParamsSchema, ); -export const validatePluginApprovalRequestParams = ajv.compile( +export const validatePluginApprovalRequestParams = lazyCompile( PluginApprovalRequestParamsSchema, ); -export const validatePluginApprovalResolveParams = ajv.compile( +export const validatePluginApprovalResolveParams = lazyCompile( PluginApprovalResolveParamsSchema, ); -export const validatePluginsUiDescriptorsParams = ajv.compile( +export const validatePluginsUiDescriptorsParams = lazyCompile( PluginsUiDescriptorsParamsSchema, ); -export const validatePluginsSessionActionParams = ajv.compile( +export const validatePluginsSessionActionParams = lazyCompile( PluginsSessionActionParamsSchema, ); -export const validatePluginsSessionActionResult = ajv.compile( +export const validatePluginsSessionActionResult = lazyCompile( PluginsSessionActionResultSchema, ); -export const validateExecApprovalsNodeGetParams = ajv.compile( +export const validateExecApprovalsNodeGetParams = lazyCompile( ExecApprovalsNodeGetParamsSchema, ); -export const validateExecApprovalsNodeSetParams = ajv.compile( +export const validateExecApprovalsNodeSetParams = lazyCompile( ExecApprovalsNodeSetParamsSchema, ); -export const validateLogsTailParams = ajv.compile(LogsTailParamsSchema); -export const validateChatHistoryParams = ajv.compile(ChatHistoryParamsSchema); -export const validateChatSendParams = ajv.compile(ChatSendParamsSchema); -export const validateChatAbortParams = ajv.compile(ChatAbortParamsSchema); -export const validateChatInjectParams = ajv.compile(ChatInjectParamsSchema); -export const validateChatEvent = ajv.compile(ChatEventSchema); -export const validateUpdateStatusParams = ajv.compile(UpdateStatusParamsSchema); -export const validateUpdateRunParams = ajv.compile(UpdateRunParamsSchema); +export const validateLogsTailParams = lazyCompile(LogsTailParamsSchema); +export const validateChatHistoryParams = lazyCompile(ChatHistoryParamsSchema); +export const validateChatSendParams = lazyCompile(ChatSendParamsSchema); +export const validateChatAbortParams = lazyCompile(ChatAbortParamsSchema); +export const validateChatInjectParams = lazyCompile(ChatInjectParamsSchema); +export const validateChatEvent = lazyCompile(ChatEventSchema); +export const validateUpdateStatusParams = lazyCompile(UpdateStatusParamsSchema); +export const validateUpdateRunParams = lazyCompile(UpdateRunParamsSchema); export const validateWebLoginStartParams = - ajv.compile(WebLoginStartParamsSchema); -export const validateWebLoginWaitParams = ajv.compile(WebLoginWaitParamsSchema); + lazyCompile(WebLoginStartParamsSchema); +export const validateWebLoginWaitParams = lazyCompile(WebLoginWaitParamsSchema); export function formatValidationErrors(errors: ErrorObject[] | null | undefined) { if (!errors?.length) { @@ -775,7 +842,7 @@ export function formatValidationErrors(errors: ErrorObject[] | null | undefined) // De-dupe while preserving order. const unique = Array.from(new Set(parts.filter((part) => part.trim()))); if (!unique.length) { - const fallback = ajv.errorsText(errors, { separator: "; " }); + const fallback = getAjv().errorsText(errors, { separator: "; " }); return fallback || "unknown validation error"; } return unique.join("; ");