bazis 0.96.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -0
  3. package/cli/build.ts +147 -0
  4. package/cli/codegen.ts +40 -0
  5. package/cli/generateModule.ts +187 -0
  6. package/cli/generateProject.ts +183 -0
  7. package/cli/main.ts +125 -0
  8. package/cli/moduleRegistration.ts +127 -0
  9. package/cli/naming.ts +124 -0
  10. package/cli/parseCli.ts +151 -0
  11. package/cli/templates/module.ts +497 -0
  12. package/cli/templates/pack.ts +76 -0
  13. package/cli/templates/passport.ts +178 -0
  14. package/core/agent/AgentContextBuilder.ts +567 -0
  15. package/core/agent/AgentDataDefinition.ts +8 -0
  16. package/core/agent/AgentRegistry.ts +539 -0
  17. package/core/agent/AgentRuntime.ts +47 -0
  18. package/core/agent/AgentToolExecutor.ts +2130 -0
  19. package/core/agent/AgentToolHooks.ts +39 -0
  20. package/core/agent/ModelProvider.ts +21 -0
  21. package/core/agent/README.md +229 -0
  22. package/core/agent/Tool.contract.ts +20 -0
  23. package/core/agent/decorators/Agent.ts +11 -0
  24. package/core/agent/decorators/Prompt.ts +11 -0
  25. package/core/agent/decorators/Task.ts +29 -0
  26. package/core/agent/decorators/Tool.ts +12 -0
  27. package/core/agent/errors.ts +43 -0
  28. package/core/agent/generated/catalog.ts +26 -0
  29. package/core/agent/index.ts +170 -0
  30. package/core/agent/internal/AgentExecutionDriver.ts +1497 -0
  31. package/core/agent/internal/AgentExecutionState.ts +775 -0
  32. package/core/agent/internal/AgentJsonSchema.ts +150 -0
  33. package/core/agent/internal/AgentModelBinding.ts +57 -0
  34. package/core/agent/internal/Schema.contract.ts +36 -0
  35. package/core/agent/internal/ToolAudit.projector.ts +163 -0
  36. package/core/agent/internal/ToolContract.validator.ts +102 -0
  37. package/core/agent/metadata.ts +398 -0
  38. package/core/agent/moduleContributions-v1.ts +113 -0
  39. package/core/agent/semantic.ts +903 -0
  40. package/core/agent/session/codec.ts +33 -0
  41. package/core/agent/session/contracts.ts +96 -0
  42. package/core/agent/session/entities.ts +84 -0
  43. package/core/agent/session/protector.ts +92 -0
  44. package/core/app/index.ts +5 -0
  45. package/core/app/runApp.ts +293 -0
  46. package/core/app/ui/index.ts +29 -0
  47. package/core/app/ui/uiProfileResolver.ts +966 -0
  48. package/core/app/ui/uiSurfaceHosting.ts +38 -0
  49. package/core/app/ui/uiSurfaceHttp.ts +476 -0
  50. package/core/background/BackgroundService.ts +223 -0
  51. package/core/background/backgroundModule.ts +42 -0
  52. package/core/background/decorator.ts +43 -0
  53. package/core/background/delay.ts +27 -0
  54. package/core/background/index.ts +15 -0
  55. package/core/cache/COMPATIBILITY.md +13 -0
  56. package/core/cache/ICache.ts +71 -0
  57. package/core/cache/MemoryCache.ts +394 -0
  58. package/core/cache/README.md +83 -0
  59. package/core/cache/SPEC.md +1355 -0
  60. package/core/cache/cacheModule.ts +21 -0
  61. package/core/cache/decorators/Cacheable.ts +38 -0
  62. package/core/cache/decorators/CacheableRedis.ts +39 -0
  63. package/core/cache/decorators/OutputCache.ts +33 -0
  64. package/core/cache/decorators/OutputRedisCache.ts +33 -0
  65. package/core/cache/decorators/cacheableMetadata.ts +78 -0
  66. package/core/cache/decorators/cacheableRedisMetadata.ts +81 -0
  67. package/core/cache/decorators/outputCacheMetadata.ts +71 -0
  68. package/core/cache/decorators/outputRedisCacheMetadata.ts +77 -0
  69. package/core/cache/di/classProviderHook.ts +26 -0
  70. package/core/cache/distributed/CacheCodec.ts +5 -0
  71. package/core/cache/distributed/DistributedCache.ts +403 -0
  72. package/core/cache/distributed/DistributedCacheDriver.ts +83 -0
  73. package/core/cache/distributed/DistributedCacheStores.ts +28 -0
  74. package/core/cache/distributed/IDistributedCache.ts +40 -0
  75. package/core/cache/distributed/NamedCacheRegistry.ts +23 -0
  76. package/core/cache/distributed/codecs.ts +32 -0
  77. package/core/cache/distributed/index.ts +19 -0
  78. package/core/cache/errors/CacheError.ts +16 -0
  79. package/core/cache/http/CachedHttpPayload.ts +213 -0
  80. package/core/cache/http/applyClientCacheHeaders.ts +61 -0
  81. package/core/cache/http/buildOutputCacheKey.ts +154 -0
  82. package/core/cache/http/buildRedisOutputCacheKey.ts +16 -0
  83. package/core/cache/http/composeOutputCache.ts +130 -0
  84. package/core/cache/http/outputCacheMiddleware.ts +111 -0
  85. package/core/cache/http/outputCacheSecurityWarning.ts +58 -0
  86. package/core/cache/http/outputRedisCacheMiddleware.ts +118 -0
  87. package/core/cache/index.ts +97 -0
  88. package/core/cache/internal/AutomaticCacheKey.ts +106 -0
  89. package/core/cache/internal/CacheKeyGuard.ts +56 -0
  90. package/core/cache/internal/buildCacheProviders.ts +146 -0
  91. package/core/cache/internal/normalizeCacheKey.ts +9 -0
  92. package/core/cache/internal/resolveCachePolicy.ts +32 -0
  93. package/core/cache/internal/resolveCacheableRedisPolicy.ts +17 -0
  94. package/core/cache/internal/resolveOutputRedisCachePolicy.ts +17 -0
  95. package/core/cache/providers/cachedProviders.ts +68 -0
  96. package/core/cache/services/cacheProxy.ts +243 -0
  97. package/core/cache/tokens/CACHE_POLICIES.ts +5 -0
  98. package/core/cache/tokens/DISTRIBUTED_CACHE.ts +30 -0
  99. package/core/cache/types/CacheEntry.ts +7 -0
  100. package/core/cache/types/CacheOptions.ts +60 -0
  101. package/core/cache/types/CachePolicy.ts +74 -0
  102. package/core/cache/types/CacheableRedisOptions.ts +23 -0
  103. package/core/cache/types/OutputRedisCacheOptions.ts +25 -0
  104. package/core/di/README.md +104 -0
  105. package/core/di/ServiceCollection.ts +185 -0
  106. package/core/di/ServiceProvider.ts +689 -0
  107. package/core/di/ServiceScope.ts +61 -0
  108. package/core/di/container.ts +38 -0
  109. package/core/di/errors/AmbiguousNamedDependencyError.ts +10 -0
  110. package/core/di/errors/AsyncResolutionRequiredError.ts +12 -0
  111. package/core/di/errors/CircularDependencyError.ts +10 -0
  112. package/core/di/errors/ClassDependenciesMismatchError.ts +15 -0
  113. package/core/di/errors/DiError.ts +6 -0
  114. package/core/di/errors/InvalidProviderError.ts +9 -0
  115. package/core/di/errors/ModuleEncapsulationError.ts +7 -0
  116. package/core/di/errors/ModuleOwnedProviderConflictError.ts +8 -0
  117. package/core/di/errors/NamedDependencyNotFoundError.ts +7 -0
  118. package/core/di/errors/OptionsValidationError.ts +7 -0
  119. package/core/di/errors/ProviderNotFoundError.ts +10 -0
  120. package/core/di/errors/ScopeDisposedError.ts +7 -0
  121. package/core/di/errors/ScopedServiceFromRootError.ts +9 -0
  122. package/core/di/errors/ServiceValidationError.ts +7 -0
  123. package/core/di/errors/index.ts +14 -0
  124. package/core/di/extensions/activator.ts +39 -0
  125. package/core/di/extensions/application.ts +117 -0
  126. package/core/di/extensions/hosted-service.ts +124 -0
  127. package/core/di/extensions/index.ts +23 -0
  128. package/core/di/extensions/options-reloadable.ts +137 -0
  129. package/core/di/extensions/options.ts +91 -0
  130. package/core/di/extensions/service-provider-token.ts +21 -0
  131. package/core/di/index.ts +97 -0
  132. package/core/di/internal/GraphValidator.ts +119 -0
  133. package/core/di/internal/HostedServicePlan.ts +158 -0
  134. package/core/di/internal/NamedTokenIndex.ts +55 -0
  135. package/core/di/internal/OpenGenericRegistration.ts +14 -0
  136. package/core/di/internal/ResolutionPlan.ts +18 -0
  137. package/core/di/internal/ResolutionScopeState.ts +19 -0
  138. package/core/di/internal/ResolutionTracker.ts +153 -0
  139. package/core/di/internal/ScopeLifecycle.ts +159 -0
  140. package/core/di/internal/ServiceRegistration.ts +14 -0
  141. package/core/di/internal/ServiceRegistry.ts +252 -0
  142. package/core/di/internal/classDeps.ts +38 -0
  143. package/core/di/internal/disposal.ts +58 -0
  144. package/core/di/internal/providerDeps.ts +26 -0
  145. package/core/di/module/DI.ts +146 -0
  146. package/core/di/module/Global.ts +25 -0
  147. package/core/di/module/Module.ts +44 -0
  148. package/core/di/module/ModuleRegistrar.ts +69 -0
  149. package/core/di/module/autoDeps.ts +39 -0
  150. package/core/di/module/classProviderHooks.ts +66 -0
  151. package/core/di/module/collectModuleConfigs.ts +57 -0
  152. package/core/di/module/collectModuleControllers.ts +53 -0
  153. package/core/di/module/collectModuleUiProfiles.ts +53 -0
  154. package/core/di/module/createContainer.ts +261 -0
  155. package/core/di/module/encapsulation.ts +416 -0
  156. package/core/di/module/encapsulationHooks.ts +36 -0
  157. package/core/di/module/generatedProviderAttachments.ts +102 -0
  158. package/core/di/module/index.ts +41 -0
  159. package/core/di/module/moduleExtensions.ts +35 -0
  160. package/core/di/module/moduleNameBinding.ts +136 -0
  161. package/core/di/module/moduleOwnedProviderContributors.ts +409 -0
  162. package/core/di/module/providerSelection.ts +90 -0
  163. package/core/di/module/shortcuts.ts +111 -0
  164. package/core/di/module/types/BazisModule.ts +71 -0
  165. package/core/di/module/types/DiRegistrar.ts +24 -0
  166. package/core/di/module/types/index.ts +2 -0
  167. package/core/di/provider/index.ts +26 -0
  168. package/core/di/provider/providerGuards.ts +17 -0
  169. package/core/di/provider/types/AsyncFactoryProvider.ts +15 -0
  170. package/core/di/provider/types/ClassProvider.ts +18 -0
  171. package/core/di/provider/types/FactoryProvider.ts +20 -0
  172. package/core/di/provider/types/KeyedDependency.ts +20 -0
  173. package/core/di/provider/types/LazyDependency.ts +31 -0
  174. package/core/di/provider/types/NamedDependency.ts +16 -0
  175. package/core/di/provider/types/Provider.ts +10 -0
  176. package/core/di/provider/types/ProviderDefinition.ts +11 -0
  177. package/core/di/provider/types/ProviderDependencyList.ts +11 -0
  178. package/core/di/provider/types/ProviderLifetime.ts +1 -0
  179. package/core/di/provider/types/ProviderOwnership.ts +7 -0
  180. package/core/di/provider/types/ResolvedDeps.ts +18 -0
  181. package/core/di/provider/types/ValueProvider.ts +6 -0
  182. package/core/di/provider/types/index.ts +13 -0
  183. package/core/di/token.ts +84 -0
  184. package/core/di/types/BuildServiceProviderOptions.ts +4 -0
  185. package/core/di/types/ServiceKey.ts +1 -0
  186. package/core/di/types/ServiceResolver.ts +16 -0
  187. package/core/di/types/index.ts +3 -0
  188. package/core/generatedFingerprint.ts +60 -0
  189. package/core/generatedRuntime.ts +187 -0
  190. package/core/grpc/Grpc.module.ts +23 -0
  191. package/core/grpc/GrpcBinding.contract.ts +35 -0
  192. package/core/grpc/GrpcCall.ts +73 -0
  193. package/core/grpc/GrpcClient.ts +172 -0
  194. package/core/grpc/GrpcClientCall.ts +267 -0
  195. package/core/grpc/GrpcError.ts +19 -0
  196. package/core/grpc/GrpcRequest.binding.ts +45 -0
  197. package/core/grpc/GrpcServer.ts +204 -0
  198. package/core/grpc/GrpcStatus.ts +8 -0
  199. package/core/grpc/GrpcTransport.ts +174 -0
  200. package/core/grpc/Metadata.ts +73 -0
  201. package/core/grpc/ProtoCodec.ts +225 -0
  202. package/core/grpc/ProtoParser.ts +192 -0
  203. package/core/grpc/ProtoReader.ts +34 -0
  204. package/core/grpc/ProtoSchema.ts +52 -0
  205. package/core/grpc/ServerCredentials.ts +30 -0
  206. package/core/grpc/clientContracts.ts +39 -0
  207. package/core/grpc/contracts.ts +45 -0
  208. package/core/grpc/decorators.ts +82 -0
  209. package/core/grpc/grpcClientProvider.ts +9 -0
  210. package/core/grpc/index.ts +17 -0
  211. package/core/grpc/moduleControllers.ts +38 -0
  212. package/core/grpc/protobuf.ts +80 -0
  213. package/core/grpc/serviceDefinition.ts +20 -0
  214. package/core/http/Authorization/Authorize.ts +52 -0
  215. package/core/http/Authorization/authorizeComposer.ts +31 -0
  216. package/core/http/Authorization/metadata.ts +158 -0
  217. package/core/http/Binding/ParameterBinder.ts +109 -0
  218. package/core/http/Binding/RequestModel.ts +27 -0
  219. package/core/http/Binding/autoBindings.ts +125 -0
  220. package/core/http/Binding/bindings.ts +19 -0
  221. package/core/http/Binding/convert.ts +48 -0
  222. package/core/http/Binding/generatedSpec.ts +18 -0
  223. package/core/http/Binding/listModelRegistry.ts +47 -0
  224. package/core/http/Binding/modelBinder.ts +345 -0
  225. package/core/http/Binding/modelValidator.ts +30 -0
  226. package/core/http/Binding/requestModelRegistry.ts +117 -0
  227. package/core/http/Decorators/attributes.ts +92 -0
  228. package/core/http/Decorators/controller.ts +24 -0
  229. package/core/http/Decorators/metadata.ts +107 -0
  230. package/core/http/Decorators/routes.ts +131 -0
  231. package/core/http/Errors/HttpError.ts +92 -0
  232. package/core/http/HttpContext/HttpContext.ts +148 -0
  233. package/core/http/HttpContext/ResponseBuilder.ts +37 -0
  234. package/core/http/HttpContext/inspectableRedirects.ts +47 -0
  235. package/core/http/HttpContext/principal.ts +24 -0
  236. package/core/http/HttpContext/responseLifetime.ts +45 -0
  237. package/core/http/HttpServer.ts +627 -0
  238. package/core/http/Middleware/accessLog.ts +90 -0
  239. package/core/http/Middleware/cors.ts +160 -0
  240. package/core/http/Middleware/errorHandler.ts +100 -0
  241. package/core/http/Middleware/pipeline.ts +21 -0
  242. package/core/http/Middleware/rateLimit.ts +104 -0
  243. package/core/http/Middleware/securityHeaders.ts +118 -0
  244. package/core/http/Middleware/types.ts +19 -0
  245. package/core/http/OpenApi/generatedOpenApiRegistry.ts +102 -0
  246. package/core/http/OpenApi/openApiDocs.ts +75 -0
  247. package/core/http/OpenApi/openApiDocument.ts +356 -0
  248. package/core/http/README.md +139 -0
  249. package/core/http/Results/HttpResult.ts +19 -0
  250. package/core/http/Results/normalize.ts +93 -0
  251. package/core/http/Results/results.ts +70 -0
  252. package/core/http/Routing/Router.ts +201 -0
  253. package/core/http/Routing/RouterBuilder.ts +184 -0
  254. package/core/http/Routing/template.ts +112 -0
  255. package/core/http/SPEC.md +981 -0
  256. package/core/http/Versioning/VersionReader.ts +20 -0
  257. package/core/http/WebSocketUpgrade.ts +29 -0
  258. package/core/http/composeRouteMiddlewareComposers.ts +21 -0
  259. package/core/http/correlation/createCorrelationIdMiddleware.ts +79 -0
  260. package/core/http/httpModule.ts +48 -0
  261. package/core/http/index.ts +140 -0
  262. package/core/http/middlewareTokens.ts +48 -0
  263. package/core/http/options.ts +134 -0
  264. package/core/http-client/index.ts +105 -0
  265. package/core/infra/Infra.ts +158 -0
  266. package/core/infra/InfraConnector.ts +86 -0
  267. package/core/infra/InfraLifecycle.ts +86 -0
  268. package/core/infra/cache/RedisDistributedCacheBackend.ts +88 -0
  269. package/core/infra/cache/RedisDistributedCacheDriver.ts +186 -0
  270. package/core/infra/cache/index.ts +7 -0
  271. package/core/infra/connectorConfig.ts +29 -0
  272. package/core/infra/connectorIdentity.ts +39 -0
  273. package/core/infra/connectors/codex/CodexAppServer.ts +146 -0
  274. package/core/infra/connectors/codex/CodexAppServerClient.ts +258 -0
  275. package/core/infra/connectors/codex/CodexPolicy.ts +114 -0
  276. package/core/infra/connectors/codex/CodexTurn.ts +133 -0
  277. package/core/infra/connectors/codex/contracts.ts +82 -0
  278. package/core/infra/connectors/codex.ts +26 -0
  279. package/core/infra/connectors/llm.ts +78 -0
  280. package/core/infra/connectors/llmRouter.ts +443 -0
  281. package/core/infra/connectors/openaiCompatible.ts +590 -0
  282. package/core/infra/connectors/openaiTextStream.ts +134 -0
  283. package/core/infra/connectors/opensearch.ts +307 -0
  284. package/core/infra/connectors/postgres.ts +105 -0
  285. package/core/infra/connectors/redis.ts +132 -0
  286. package/core/infra/index.ts +58 -0
  287. package/core/kernel/ApplicationLifetime.ts +91 -0
  288. package/core/kernel/Bazis.ts +73 -0
  289. package/core/kernel/Environment.ts +53 -0
  290. package/core/kernel/Kernel.ts +391 -0
  291. package/core/kernel/KernelBuilder.ts +172 -0
  292. package/core/kernel/LifecycleCoordinator.ts +204 -0
  293. package/core/kernel/README.md +66 -0
  294. package/core/kernel/SupervisedHostedService.ts +147 -0
  295. package/core/kernel/config/ConfigRegistry.ts +48 -0
  296. package/core/kernel/config/Configuration.ts +110 -0
  297. package/core/kernel/config/README.md +62 -0
  298. package/core/kernel/config/Secret.ts +29 -0
  299. package/core/kernel/config/addConfigOptions.ts +63 -0
  300. package/core/kernel/config/defineConfig.ts +211 -0
  301. package/core/kernel/config/sources.ts +123 -0
  302. package/core/kernel/correlation/requestContext.ts +57 -0
  303. package/core/kernel/errors/ConfigKeyMissingError.ts +7 -0
  304. package/core/kernel/errors/KernelError.ts +7 -0
  305. package/core/kernel/errors/ShutdownTimeoutError.ts +7 -0
  306. package/core/kernel/errors/StartupAbortedError.ts +7 -0
  307. package/core/kernel/errors/StartupTimeoutError.ts +7 -0
  308. package/core/kernel/errors/index.ts +5 -0
  309. package/core/kernel/events/EventBus.ts +140 -0
  310. package/core/kernel/events/EventToken.ts +17 -0
  311. package/core/kernel/events/eventSubscribers.ts +126 -0
  312. package/core/kernel/events/kernelEvents.ts +16 -0
  313. package/core/kernel/events/onEvent.ts +32 -0
  314. package/core/kernel/health/HealthCheckContracts.ts +42 -0
  315. package/core/kernel/health/HealthService.ts +93 -0
  316. package/core/kernel/index.ts +96 -0
  317. package/core/kernel/internal/awaitAbortable.ts +18 -0
  318. package/core/kernel/internal/awaitShutdown.ts +21 -0
  319. package/core/kernel/internal/reportDiagnosticFailure.ts +8 -0
  320. package/core/kernel/internal/validateTimeout.ts +8 -0
  321. package/core/kernel/lifecycleHooks.ts +18 -0
  322. package/core/kernel/logging/ConsoleLogger.ts +68 -0
  323. package/core/kernel/logging/Logger.ts +22 -0
  324. package/core/kernel/types/ConfigSource.ts +9 -0
  325. package/core/kernel/types/EnvironmentName.ts +1 -0
  326. package/core/kernel/types/KernelOptions.ts +23 -0
  327. package/core/kernel/types/LifecycleHook.ts +18 -0
  328. package/core/kernel/types/index.ts +4 -0
  329. package/core/orm/DATABASE_PROVIDER.ts +5 -0
  330. package/core/orm/OrmHostedPlan.validator.ts +55 -0
  331. package/core/orm/OrmLifecycle.ts +146 -0
  332. package/core/orm/OrmOwnedStoreLifecycle.ts +96 -0
  333. package/core/orm/buildOrmProviders.ts +152 -0
  334. package/core/orm/databaseConnector.ts +108 -0
  335. package/core/orm/encapsulationHook.ts +19 -0
  336. package/core/orm/index.ts +95 -0
  337. package/core/orm/listQuery.ts +198 -0
  338. package/core/orm/ormModule.ts +173 -0
  339. package/core/orm/ownedStoreContributions.ts +195 -0
  340. package/core/orm/registerRepositories.ts +27 -0
  341. package/core/orm/repository.ts +45 -0
  342. package/core/orm/strictSchemaHostedIdentity.ts +17 -0
  343. package/core/scripts/agent-codegen.ts +1166 -0
  344. package/core/scripts/di-generate-target.ts +90 -0
  345. package/core/scripts/di-generate.ts +1837 -0
  346. package/core/scripts/orm-predicate-codegen.ts +33 -0
  347. package/core/scripts/request-model-codegen.ts +326 -0
  348. package/core/websocket/DESIGN.md +297 -0
  349. package/core/websocket/WsRateLimiter.ts +101 -0
  350. package/core/websocket/adapter/adapter.interface.ts +45 -0
  351. package/core/websocket/adapter/in-memory.adapter.ts +190 -0
  352. package/core/websocket/adapter/redis-delivery-scripts.ts +135 -0
  353. package/core/websocket/adapter/redis-delivery-store.ts +86 -0
  354. package/core/websocket/adapter/redis-operations.ts +33 -0
  355. package/core/websocket/adapter/redis.adapter.ts +218 -0
  356. package/core/websocket/codec/binary.codec.ts +87 -0
  357. package/core/websocket/codec/json.codec.ts +34 -0
  358. package/core/websocket/codec/packet-codec.interface.ts +17 -0
  359. package/core/websocket/decorators.ts +165 -0
  360. package/core/websocket/explorer.ts +126 -0
  361. package/core/websocket/index.ts +78 -0
  362. package/core/websocket/middleware.ts +146 -0
  363. package/core/websocket/packet-codec.ts +75 -0
  364. package/core/websocket/reliable-delivery.ts +56 -0
  365. package/core/websocket/session-creation.ts +16 -0
  366. package/core/websocket/session-manager.ts +856 -0
  367. package/core/websocket/socket-wrapper.ts +314 -0
  368. package/core/websocket/topic-cache.ts +59 -0
  369. package/core/websocket/types.ts +122 -0
  370. package/core/websocket/websocketModule.ts +96 -0
  371. package/core/websocket/ws-dispatch.ts +123 -0
  372. package/core/websocket/ws-server.ts +1707 -0
  373. package/index.ts +281 -0
  374. package/library/boundary/diagnostics-v1.ts +136 -0
  375. package/library/boundary/index.ts +73 -0
  376. package/library/boundary/json/decodeBoundedJsonV1.ts +518 -0
  377. package/library/boundary/json/limits-v1.ts +46 -0
  378. package/library/boundary/json/normalizeBoundedJsonV1.ts +256 -0
  379. package/library/boundary/json/types-v1.ts +11 -0
  380. package/library/boundary/schema/boundarySchemaHashV1.ts +6 -0
  381. package/library/boundary/schema/collectBoundaryValueDiagnosticsV1.ts +325 -0
  382. package/library/boundary/schema/decodeBoundarySchemaV1.ts +646 -0
  383. package/library/boundary/schema/index.ts +8 -0
  384. package/library/boundary/schema/types-v1.ts +99 -0
  385. package/library/boundary/schema/validateBoundaryValueV1.ts +58 -0
  386. package/library/boundary/serialization/canonicalJsonV1.ts +66 -0
  387. package/library/http-client/HttpClient.ts +969 -0
  388. package/library/http-client/HttpClientFactory.ts +45 -0
  389. package/library/http-client/errors.ts +68 -0
  390. package/library/http-client/index.ts +43 -0
  391. package/library/http-client/interceptors.ts +40 -0
  392. package/library/http-client/progress.ts +62 -0
  393. package/library/http-client/redirectProtocol.ts +6 -0
  394. package/library/http-client/serialize.ts +133 -0
  395. package/library/http-client/types.ts +174 -0
  396. package/library/jsonapi/ListQueryError.ts +25 -0
  397. package/library/jsonapi/ListRequest.ts +37 -0
  398. package/library/jsonapi/decorators.ts +161 -0
  399. package/library/jsonapi/document.ts +124 -0
  400. package/library/jsonapi/index.ts +40 -0
  401. package/library/jsonapi/parseListQuery.ts +291 -0
  402. package/library/jsonapi/types.ts +125 -0
  403. package/library/jwt/JwtEncoder.ts +40 -0
  404. package/library/jwt/JwtKeyRing.ts +164 -0
  405. package/library/jwt/JwtValidator.ts +210 -0
  406. package/library/jwt/TokenIssuer.ts +149 -0
  407. package/library/jwt/TokenService.ts +51 -0
  408. package/library/jwt/base64url.ts +61 -0
  409. package/library/jwt/claims.ts +36 -0
  410. package/library/jwt/errors.ts +44 -0
  411. package/library/jwt/index.ts +59 -0
  412. package/library/jwt/limits.ts +8 -0
  413. package/library/jwt/signing/Hs256Algorithm.ts +62 -0
  414. package/library/jwt/signing/Rs256Algorithm.ts +133 -0
  415. package/library/jwt/signing/SigningAlgorithm.ts +18 -0
  416. package/library/jwt/signing/pem.ts +30 -0
  417. package/library/openapi/codegen.ts +875 -0
  418. package/library/openapi/document.ts +326 -0
  419. package/library/openapi/index.ts +13 -0
  420. package/library/openapi/types.ts +69 -0
  421. package/library/openapi/ui.ts +182 -0
  422. package/library/orm/DatabaseFacade.ts +209 -0
  423. package/library/orm/DbContext.ts +107 -0
  424. package/library/orm/DbContextFactory.ts +25 -0
  425. package/library/orm/DbContextOptions.ts +33 -0
  426. package/library/orm/Metadata/DynamicModelBuilder.ts +497 -0
  427. package/library/orm/Metadata/KeyTuple.ts +36 -0
  428. package/library/orm/Metadata/ModelBuilder.ts +299 -0
  429. package/library/orm/Metadata/OrmModel.ts +80 -0
  430. package/library/orm/Metadata/ValueConverter.ts +57 -0
  431. package/library/orm/Metadata/conventions.ts +54 -0
  432. package/library/orm/Metadata/decorators.ts +396 -0
  433. package/library/orm/Metadata/types.ts +140 -0
  434. package/library/orm/Providers/OwnedStoreCatalog.reader.ts +1802 -0
  435. package/library/orm/Providers/PostgresDialect.ts +234 -0
  436. package/library/orm/Providers/PostgresProvider.ts +1494 -0
  437. package/library/orm/Providers/PostgresSchema.decoder.ts +107 -0
  438. package/library/orm/Providers/limits.ts +29 -0
  439. package/library/orm/Providers/operationDeadline.ts +43 -0
  440. package/library/orm/Providers/ormOwnedStoreRuntime.ts +19 -0
  441. package/library/orm/Providers/ormTransactionRuntime.ts +117 -0
  442. package/library/orm/Providers/propertyConversion.ts +14 -0
  443. package/library/orm/Providers/resolvedForeignKey.ts +16 -0
  444. package/library/orm/Providers/transactionCallbacks.ts +45 -0
  445. package/library/orm/Providers/transactionOutcome.ts +82 -0
  446. package/library/orm/Providers/transactionScopes.ts +78 -0
  447. package/library/orm/Providers/types.ts +207 -0
  448. package/library/orm/Query/DbSet.ts +78 -0
  449. package/library/orm/Query/EntityQuery.ts +247 -0
  450. package/library/orm/Query/ImmediateMutations.ts +226 -0
  451. package/library/orm/Query/IncludeLoader.ts +200 -0
  452. package/library/orm/Query/QueryPlan.ts +55 -0
  453. package/library/orm/Query/SqlTranslator.ts +195 -0
  454. package/library/orm/Query/conditions.ts +127 -0
  455. package/library/orm/Query/materialize.ts +39 -0
  456. package/library/orm/README.md +256 -0
  457. package/library/orm/Repository/README.md +684 -0
  458. package/library/orm/Repository/Repository.ts +68 -0
  459. package/library/orm/Saving/CommandBuilder.ts +139 -0
  460. package/library/orm/Saving/ExecutionStrategy.ts +128 -0
  461. package/library/orm/Saving/SaveExecutor.ts +413 -0
  462. package/library/orm/Saving/applyConventions.ts +64 -0
  463. package/library/orm/Schema/CheckExpression.ts +327 -0
  464. package/library/orm/Schema/ExactSchemaVerifier.ts +168 -0
  465. package/library/orm/Schema/ExpectedSchema.ts +43 -0
  466. package/library/orm/Schema/MigrationRunner.ts +146 -0
  467. package/library/orm/Schema/Migrator.ts +73 -0
  468. package/library/orm/Schema/OrmOwnedStore.ts +123 -0
  469. package/library/orm/Schema/OwnedStoreAdmission.ts +752 -0
  470. package/library/orm/Schema/OwnedStoreCanonical.ts +273 -0
  471. package/library/orm/Schema/OwnedStoreCatalog.ts +1325 -0
  472. package/library/orm/Schema/SafeAdditiveSchema.ts +100 -0
  473. package/library/orm/Schema/SchemaAdmission.ts +62 -0
  474. package/library/orm/Schema/SchemaDiffer.ts +78 -0
  475. package/library/orm/Schema/formatSchemaDifferences.ts +62 -0
  476. package/library/orm/Schema/introspection.ts +52 -0
  477. package/library/orm/Schema/physicalColumnTypes.ts +37 -0
  478. package/library/orm/Schema/tableKey.ts +26 -0
  479. package/library/orm/Tracking/ChangeTracker.ts +448 -0
  480. package/library/orm/Tracking/EntityState.ts +13 -0
  481. package/library/orm/Transactions/OrmTransaction.ts +30 -0
  482. package/library/orm/Transactions/TransactionScopeCoordinator.ts +377 -0
  483. package/library/orm/errors.ts +190 -0
  484. package/library/orm/index.ts +162 -0
  485. package/library/orm/runtime.ts +14 -0
  486. package/library/redaction/index.ts +166 -0
  487. package/library/ui/UiProfile.ts +77 -0
  488. package/library/ui/compiled-v1.ts +131 -0
  489. package/library/ui/compiler/compileUiSurfaceV1.ts +717 -0
  490. package/library/ui/compiler/contracts-v1.ts +25 -0
  491. package/library/ui/compiler/index.ts +12 -0
  492. package/library/ui/compiler/openApiIndex.ts +246 -0
  493. package/library/ui/defineUiProfile.ts +340 -0
  494. package/library/ui/diagnostics-v1.ts +33 -0
  495. package/library/ui/index.ts +129 -0
  496. package/library/ui/profile-v1.ts +191 -0
  497. package/library/ui/serialization.ts +130 -0
  498. package/library/ui/uiProfileAuthoring.ts +289 -0
  499. package/library/ui/uiProfileAuthoringMetadata.ts +78 -0
  500. package/library/validation/MessageRegistry.ts +144 -0
  501. package/library/validation/README.md +62 -0
  502. package/library/validation/RuleCompiler.ts +183 -0
  503. package/library/validation/RuleEngine.ts +401 -0
  504. package/library/validation/SPEC.md +579 -0
  505. package/library/validation/ValidationError.ts +37 -0
  506. package/library/validation/ValidationResult.ts +63 -0
  507. package/library/validation/Validator.ts +101 -0
  508. package/library/validation/index.ts +16 -0
  509. package/library/validation/metadata.ts +69 -0
  510. package/library/validation/modelValidatorAdapter.ts +119 -0
  511. package/library/validation/types/ValidationCode.ts +69 -0
  512. package/library/validation/types/ValidatorOptions.ts +153 -0
  513. package/package.json +80 -0
@@ -0,0 +1,150 @@
1
+ import { validateBoundaryValueV1 } from "../../../library/boundary";
2
+
3
+ type Schema = boolean | Readonly<Record<string, unknown>>;
4
+ const TYPES = new Set(["object", "array", "string", "number", "integer", "boolean", "null"]);
5
+ const FORMATS = new Set(["email", "uri", "uuid", "date", "time", "date-time", "decimal", "int64-string"]);
6
+ const ANNOTATIONS = new Set(["title", "description", "default", "examples", "example", "readOnly", "writeOnly", "deprecated", "$comment"]);
7
+ const COUNTS = new Set(["minLength", "maxLength", "minItems", "maxItems", "minProperties", "maxProperties"]);
8
+ const BOUNDS = new Set(["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum"]);
9
+ const KEYWORDS = new Set(["type", "nullable", "properties", "required", "additionalProperties", "items", "anyOf", "oneOf", "allOf", "enum", "const", "uniqueItems", "pattern", "format", "contentMediaType", ...ANNOTATIONS, ...COUNTS, ...BOUNDS]);
10
+
11
+ function record(value: unknown): value is Record<string, unknown> {
12
+ return value !== null && typeof value === "object" && !Array.isArray(value);
13
+ }
14
+
15
+ function equal(left: unknown, right: unknown): boolean {
16
+ if (left === right) return true;
17
+ if (Array.isArray(left)) return Array.isArray(right) && left.length === right.length && left.every((item, i) => equal(item, right[i]));
18
+ if (!record(left) || !record(right)) return false;
19
+ const keys = Object.keys(left);
20
+ return keys.length === Object.keys(right).length && keys.every((key) => Object.hasOwn(right, key) && equal(left[key], right[key]));
21
+ }
22
+
23
+ /** The runtime's supported JSON Schema subset. Unsupported rules fail closed. */
24
+ export function validateAgentJsonSchema(value: unknown, schema: unknown): readonly string[] {
25
+ const patterns = new Map<Schema, RegExp>();
26
+ let schemaNodes = 0;
27
+ let valueNodes = 0;
28
+ function inspect(node: unknown, path: string, depth: number): asserts node is Schema {
29
+ if (++schemaNodes > 2_048 || depth > 32) throw new Error("JSON Schema exceeds traversal limits.");
30
+ if (typeof node === "boolean") return;
31
+ if (!record(node)) throw new Error(`${path} must be a schema object or boolean.`);
32
+ for (const [key, item] of Object.entries(node)) {
33
+ if (!KEYWORDS.has(key)) throw new Error(`${path}: unsupported JSON Schema keyword "${key}".`);
34
+ if (COUNTS.has(key) && (typeof item !== "number" || !Number.isSafeInteger(item) || item < 0)) throw new Error(`${path}.${key} must be a non-negative integer.`);
35
+ if (BOUNDS.has(key) && (typeof item !== "number" || !Number.isFinite(item))) throw new Error(`${path}.${key} must be finite.`);
36
+ }
37
+ if (node.type !== undefined) {
38
+ const types = Array.isArray(node.type) ? node.type : [node.type];
39
+ if (!types.length || types.some((type) => typeof type !== "string" || !TYPES.has(type))) throw new Error(`${path}.type is unsupported.`);
40
+ }
41
+ for (const key of ["nullable", "uniqueItems"]) {
42
+ if (node[key] !== undefined && typeof node[key] !== "boolean") throw new Error(`${path}.${key} must be boolean.`);
43
+ }
44
+ if (node.required !== undefined && (!Array.isArray(node.required) || node.required.some((key) => typeof key !== "string"))) throw new Error(`${path}.required must be an array of names.`);
45
+ if (node.enum !== undefined && (!Array.isArray(node.enum) || !node.enum.length)) throw new Error(`${path}.enum must be a non-empty array.`);
46
+ if (node.properties !== undefined) {
47
+ if (!record(node.properties)) throw new Error(`${path}.properties must be an object.`);
48
+ for (const [name, child] of Object.entries(node.properties)) inspect(child, `${path}.properties.${name}`, depth + 1);
49
+ }
50
+ for (const key of ["items", "additionalProperties"]) {
51
+ if (node[key] !== undefined) inspect(node[key], `${path}.${key}`, depth + 1);
52
+ }
53
+ for (const key of ["anyOf", "oneOf", "allOf"]) {
54
+ if (node[key] === undefined) continue;
55
+ if (!Array.isArray(node[key]) || !node[key].length) throw new Error(`${path}.${key} must be a non-empty schema array.`);
56
+ node[key].forEach((child, i) => inspect(child, `${path}.${key}[${i}]`, depth + 1));
57
+ }
58
+ if (node.pattern !== undefined) {
59
+ if (typeof node.pattern !== "string") throw new Error(`${path}.pattern must be a string.`);
60
+ patterns.set(node, new RegExp(node.pattern));
61
+ }
62
+ if (node.format !== undefined && (typeof node.format !== "string" || !FORMATS.has(node.format))) throw new Error(`${path}.format is unsupported.`);
63
+ if (node.contentMediaType !== undefined && node.contentMediaType !== "application/json") throw new Error(`${path}.contentMediaType is unsupported.`);
64
+ }
65
+
66
+ function matchesType(item: unknown, type: unknown): boolean {
67
+ if (type === "null") return item === null;
68
+ if (type === "object") return record(item);
69
+ if (type === "array") return Array.isArray(item);
70
+ if (type === "integer") return typeof item === "number" && Number.isInteger(item);
71
+ if (type === "number") return typeof item === "number" && Number.isFinite(item);
72
+ return typeof item === type;
73
+ }
74
+
75
+ function check(item: unknown, node: Schema, path: string, issues: string[], depth: number): void {
76
+ if (++valueNodes > 100_000 || depth > 64) throw new Error("JSON Schema validation exceeds traversal limits.");
77
+ if (issues.length >= 64) return;
78
+ if (node === true) return;
79
+ if (node === false) { issues.push(`${path} is not allowed.`); return; }
80
+ if (item === null && node.nullable === true) return;
81
+ for (const key of ["anyOf", "oneOf", "allOf"] as const) {
82
+ const alternatives = node[key] as Schema[] | undefined;
83
+ if (alternatives === undefined) continue;
84
+ let matches = 0;
85
+ for (const child of alternatives) {
86
+ const childIssues: string[] = [];
87
+ check(item, child, path, childIssues, depth + 1);
88
+ if (!childIssues.length) matches++;
89
+ }
90
+ if ((key === "anyOf" && matches === 0) || (key === "oneOf" && matches !== 1) || (key === "allOf" && matches !== alternatives.length)) issues.push(`${path} does not satisfy ${key}.`);
91
+ }
92
+ if (Object.hasOwn(node, "const") && !equal(item, node.const)) issues.push(`${path} must equal the declared constant.`);
93
+ if (Array.isArray(node.enum) && !node.enum.some((allowed) => equal(item, allowed))) issues.push(`${path} is not an allowed enum value.`);
94
+ const types = node.type === undefined ? undefined : Array.isArray(node.type) ? node.type : [node.type];
95
+ if (types !== undefined && !types.some((type) => matchesType(item, type))) { issues.push(`${path} has an invalid type.`); return; }
96
+ if (record(item)) {
97
+ const properties = record(node.properties) ? node.properties : {};
98
+ const keys = Object.keys(item);
99
+ if (typeof node.minProperties === "number" && keys.length < node.minProperties) issues.push(`${path} has too few properties.`);
100
+ if (typeof node.maxProperties === "number" && keys.length > node.maxProperties) issues.push(`${path} has too many properties.`);
101
+ for (const key of (node.required ?? []) as string[]) if (!Object.hasOwn(item, key)) issues.push(`${path}.${key} is required.`);
102
+ for (const [key, child] of Object.entries(item)) {
103
+ const childSchema = Object.hasOwn(properties, key) ? properties[key] : node.additionalProperties;
104
+ if (childSchema !== undefined) check(child, childSchema as Schema, `${path}.${key}`, issues, depth + 1);
105
+ }
106
+ }
107
+ if (Array.isArray(item)) {
108
+ if (typeof node.minItems === "number" && item.length < node.minItems) issues.push(`${path} has too few items.`);
109
+ if (typeof node.maxItems === "number" && item.length > node.maxItems) issues.push(`${path} has too many items.`);
110
+ if (node.uniqueItems === true) {
111
+ const seen = new Set<string>();
112
+ const canonical = (value: unknown): unknown => Array.isArray(value) ? value.map(canonical) : record(value) ? Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical(value[key])])) : value;
113
+ for (const child of item) {
114
+ const key = JSON.stringify(canonical(child));
115
+ if (seen.has(key)) { issues.push(`${path} must contain unique items.`); break; }
116
+ seen.add(key);
117
+ }
118
+ }
119
+ if (node.items !== undefined) item.forEach((child, i) => check(child, node.items as Schema, `${path}[${i}]`, issues, depth + 1));
120
+ }
121
+ if (typeof item === "string") {
122
+ const length = [...item].length;
123
+ if (typeof node.minLength === "number" && length < node.minLength) issues.push(`${path} is too short.`);
124
+ if (typeof node.maxLength === "number" && length > node.maxLength) issues.push(`${path} is too long.`);
125
+ if (patterns.has(node) && !patterns.get(node)!.test(item)) issues.push(`${path} does not match pattern.`);
126
+ if (node.format !== undefined) {
127
+ // Reuse Bazis's boundary formats; URI follows the model validator.
128
+ const valid = node.format === "uri" ? URL.canParse(item) : validateBoundaryValueV1({ type: "string", format: node.format }, item).ok;
129
+ if (!valid) issues.push(`${path} does not match format ${node.format}.`);
130
+ }
131
+ if (node.contentMediaType === "application/json") {
132
+ try { JSON.parse(item); } catch { issues.push(`${path} must contain JSON.`); }
133
+ }
134
+ }
135
+ if (typeof item === "number") {
136
+ if (typeof node.minimum === "number" && item < node.minimum) issues.push(`${path} is below minimum.`);
137
+ if (typeof node.maximum === "number" && item > node.maximum) issues.push(`${path} is above maximum.`);
138
+ if (typeof node.exclusiveMinimum === "number" && item <= node.exclusiveMinimum) issues.push(`${path} is below exclusive minimum.`);
139
+ if (typeof node.exclusiveMaximum === "number" && item >= node.exclusiveMaximum) issues.push(`${path} is above exclusive maximum.`);
140
+ }
141
+ }
142
+ try {
143
+ inspect(schema, "$schema", 0);
144
+ const issues: string[] = [];
145
+ check(value, schema, "$", issues, 0);
146
+ return issues.slice(0, 64);
147
+ } catch (error) {
148
+ return [error instanceof Error ? error.message : "JSON Schema validation failed."];
149
+ }
150
+ }
@@ -0,0 +1,57 @@
1
+ import type { Class } from "../../di";
2
+ import { bindModel } from "../../http/Binding/modelBinder";
3
+ import { getGeneratedOpenApiMetadata, getGeneratedOpenApiSchemaName } from "../../http/OpenApi/generatedOpenApiRegistry";
4
+ import { ModelValidationError } from "../../http/Errors/HttpError";
5
+ import { normalizeJsonValue, type JsonObject } from "../semantic";
6
+
7
+ // Validation belongs to the Agent execution phase (and may be asynchronous).
8
+ // Never pick up an unrelated process-wide HTTP validator while hydrating a DTO.
9
+ const bindingOnly = Object.freeze({ validate: () => ({ isValid: true, errors: [] }) });
10
+
11
+ export function bindAgentModel(contract: Class<object>, value: unknown): object {
12
+ try {
13
+ return bindModel(contract, value, bindingOnly, {
14
+ unknownFields: "reject",
15
+ declaredFields(model) {
16
+ const name = getGeneratedOpenApiSchemaName(model) ?? model.name;
17
+ const properties = getGeneratedOpenApiMetadata().schemas[name]?.properties;
18
+ return properties !== null && typeof properties === "object" && !Array.isArray(properties)
19
+ ? Object.keys(properties) : undefined;
20
+ },
21
+ });
22
+ } catch (error) {
23
+ if (error instanceof ModelValidationError) {
24
+ throw new Error(error.errors.map((issue) => issue.message).join("; "), { cause: error });
25
+ }
26
+ throw error;
27
+ }
28
+ }
29
+
30
+ /** Project hydrated DTOs to JSON without calling arbitrary toJSON methods. */
31
+ export function agentModelJson(instance: object, path: string): JsonObject {
32
+ const stack = new WeakSet<object>();
33
+ let nodes = 0;
34
+ function plain(value: unknown, depth: number): unknown {
35
+ if (++nodes > 100_000 || depth > 64) throw new Error(`${path} exceeds model JSON traversal limits.`);
36
+ if (value === null || typeof value !== "object") return value;
37
+ if (stack.has(value)) throw new Error(`${path} must be acyclic JSON.`);
38
+ stack.add(value);
39
+ try {
40
+ if (Array.isArray(value)) return value.map((item) => plain(item, depth + 1));
41
+ if (Object.prototype.toString.call(value) !== "[object Object]") {
42
+ throw new Error(`${path} contains a non-JSON object.`);
43
+ }
44
+ const output = Object.create(null) as Record<string, unknown>;
45
+ const prototype = Object.getPrototypeOf(value);
46
+ const dto = prototype !== null && prototype !== Object.prototype;
47
+ for (const [key, item] of Object.entries(value)) {
48
+ // Unset optional class fields are absent in JSON. Array slots remain strict.
49
+ if (item !== undefined || !dto) output[key] = plain(item, depth + 1);
50
+ }
51
+ return output;
52
+ } finally {
53
+ stack.delete(value);
54
+ }
55
+ }
56
+ return normalizeJsonValue(plain(instance, 0), path) as JsonObject;
57
+ }
@@ -0,0 +1,36 @@
1
+ export function inlineGeneratedSchema(
2
+ value: unknown,
3
+ schemas: Readonly<Record<string, Readonly<Record<string, unknown>>>>,
4
+ stack: ReadonlySet<string> = new Set(),
5
+ depth = 0,
6
+ ): unknown {
7
+ if (depth > 32 || value === null || typeof value !== "object") {
8
+ return value;
9
+ }
10
+ if (Array.isArray(value)) {
11
+ return value.map((item) => inlineGeneratedSchema(item, schemas, stack, depth + 1));
12
+ }
13
+ const record = value as Readonly<Record<string, unknown>>;
14
+ const reference = record.$ref;
15
+ if (typeof reference === "string" && reference.startsWith("#/components/schemas/")) {
16
+ const name = reference.slice("#/components/schemas/".length);
17
+ const target = schemas[name];
18
+ if (target === undefined || stack.has(name)) {
19
+ return { type: "object" };
20
+ }
21
+ const next = new Set(stack);
22
+ next.add(name);
23
+ return inlineGeneratedSchema(target, schemas, next, depth + 1);
24
+ }
25
+ const output: Record<string, unknown> = {};
26
+ for (const [key, item] of Object.entries(record)) {
27
+ if (item !== undefined) {
28
+ output[key] = inlineGeneratedSchema(item, schemas, stack, depth + 1);
29
+ }
30
+ }
31
+ if ((output.type === "object" || output.properties !== undefined) && output.additionalProperties === undefined) {
32
+ output.additionalProperties = false;
33
+ }
34
+ return output;
35
+ }
36
+
@@ -0,0 +1,163 @@
1
+ import type { SensitiveRedactionOptions } from "../../../library/redaction";
2
+ import { redactSensitive } from "../../../library/redaction";
3
+ import type { ToolDefinition } from "../AgentRegistry";
4
+ import type { AgentToolAuditHookProjectionV1 } from "../AgentToolHooks";
5
+ import type { AgentToolCall, AgentToolResult, JsonObject, JsonValue } from "../semantic";
6
+ import { toolContractName } from "./ToolContract.validator";
7
+
8
+ export type AgentToolAuditPhase = "attempt" | "enforcement" | "result" | "settlement" | "observer";
9
+ export type AgentToolAuditFailureMode = "fail-closed" | "best-effort";
10
+
11
+ export interface AgentToolAuditToolInfo {
12
+ readonly name: string;
13
+ readonly sideEffect: ToolDefinition["metadata"]["sideEffect"];
14
+ readonly approval: ToolDefinition["metadata"]["approval"];
15
+ readonly tags: readonly string[];
16
+ readonly timeoutMs?: number;
17
+ readonly inputSchema?: string;
18
+ readonly outputSchema?: string;
19
+ }
20
+
21
+ export interface AgentToolAuditEntry {
22
+ readonly kind: "agent-tool";
23
+ readonly phase: AgentToolAuditPhase;
24
+ readonly callId: string;
25
+ readonly toolName: string;
26
+ readonly agentName?: string;
27
+ readonly invocationId?: string;
28
+ readonly attempt?: number;
29
+ readonly maxAttempts?: number;
30
+ readonly idempotencyKey?: string;
31
+ readonly input: JsonValue;
32
+ readonly tool?: AgentToolAuditToolInfo;
33
+ readonly result?: AgentToolResult;
34
+ readonly startedAtUnixMs: number;
35
+ readonly finishedAtUnixMs?: number;
36
+ readonly durationMs?: number;
37
+ readonly metadata: JsonObject;
38
+ readonly hook?: AgentToolAuditHookProjectionV1;
39
+ }
40
+
41
+ interface ToolAuditOptions {
42
+ readonly agentName?: string;
43
+ readonly invocationId?: string;
44
+ readonly auditRedaction?: SensitiveRedactionOptions | false;
45
+ }
46
+ interface ToolAuditAttempt {
47
+ readonly attempt: number;
48
+ readonly maxAttempts: number;
49
+ readonly idempotencyKey?: string;
50
+ }
51
+
52
+ /** Builds the immutable audit projection; sink delivery and failure policy stay with execution. */
53
+ export class ToolAuditProjector {
54
+ public constructor(private readonly auditRedaction: SensitiveRedactionOptions | false) {}
55
+
56
+ public create(
57
+ phase: AgentToolAuditPhase,
58
+ call: AgentToolCall,
59
+ startedAt: number,
60
+ metadata: JsonObject,
61
+ options: ToolAuditOptions,
62
+ tool?: ToolDefinition,
63
+ agentName?: string,
64
+ result?: AgentToolResult,
65
+ attempt?: ToolAuditAttempt,
66
+ ): AgentToolAuditEntry {
67
+ const finishedAt = result ? Date.now() : undefined;
68
+ const entry: {
69
+ kind: "agent-tool";
70
+ phase: AgentToolAuditPhase;
71
+ callId: string;
72
+ toolName: string;
73
+ agentName?: string;
74
+ invocationId?: string;
75
+ attempt?: number;
76
+ maxAttempts?: number;
77
+ idempotencyKey?: string;
78
+ input: JsonValue;
79
+ tool?: AgentToolAuditToolInfo;
80
+ result?: AgentToolResult;
81
+ startedAtUnixMs: number;
82
+ finishedAtUnixMs?: number;
83
+ durationMs?: number;
84
+ metadata: JsonObject;
85
+ } = {
86
+ kind: "agent-tool",
87
+ phase,
88
+ callId: call.id,
89
+ toolName: call.name,
90
+ input: this.redactAuditValue(call.input, options),
91
+ startedAtUnixMs: startedAt,
92
+ metadata: this.redactAuditValue(metadata, options) as JsonObject,
93
+ };
94
+
95
+ if (agentName !== undefined || options.agentName !== undefined) {
96
+ entry.agentName = agentName ?? options.agentName;
97
+ }
98
+ if (options.invocationId !== undefined) {
99
+ entry.invocationId = options.invocationId;
100
+ }
101
+ if (attempt !== undefined) {
102
+ entry.attempt = attempt.attempt;
103
+ entry.maxAttempts = attempt.maxAttempts;
104
+ if (attempt.idempotencyKey !== undefined) {
105
+ entry.idempotencyKey = attempt.idempotencyKey;
106
+ }
107
+ }
108
+ if (tool !== undefined) {
109
+ entry.tool = this.auditToolInfo(tool);
110
+ }
111
+ if (result !== undefined) {
112
+ entry.result = this.redactAuditValue(result, options) as AgentToolResult;
113
+ entry.finishedAtUnixMs = finishedAt;
114
+ entry.durationMs = result.durationMs ?? Math.max(0, Date.now() - startedAt);
115
+ }
116
+
117
+ return this.freezeAuditEntry(this.redactAuditValue(entry, options));
118
+ }
119
+
120
+ private redactAuditValue<T>(value: T, options: ToolAuditOptions): T {
121
+ const redaction = options.auditRedaction ?? this.auditRedaction;
122
+ return redaction === false ? value : redactSensitive(value, redaction);
123
+ }
124
+
125
+ private freezeAuditEntry(entry: AgentToolAuditEntry): AgentToolAuditEntry {
126
+ const visit = (value: unknown, seen: WeakSet<object>): void => {
127
+ if (value === null || typeof value !== "object" || seen.has(value)) return;
128
+ seen.add(value);
129
+ for (const child of Object.values(value as Record<string, unknown>)) visit(child, seen);
130
+ Object.freeze(value);
131
+ };
132
+ visit(entry, new WeakSet<object>());
133
+ return entry;
134
+ }
135
+
136
+ private auditToolInfo(tool: ToolDefinition): AgentToolAuditToolInfo {
137
+ const info: {
138
+ name: string;
139
+ sideEffect: ToolDefinition["metadata"]["sideEffect"];
140
+ approval: ToolDefinition["metadata"]["approval"];
141
+ tags: readonly string[];
142
+ timeoutMs?: number;
143
+ inputSchema?: string;
144
+ outputSchema?: string;
145
+ } = {
146
+ name: tool.metadata.name,
147
+ sideEffect: tool.metadata.sideEffect,
148
+ approval: tool.metadata.approval,
149
+ tags: Object.freeze([...tool.metadata.tags]),
150
+ };
151
+ if (tool.metadata.timeoutMs !== undefined) {
152
+ info.timeoutMs = tool.metadata.timeoutMs;
153
+ }
154
+ if (tool.metadata.input !== undefined) {
155
+ info.inputSchema = toolContractName(tool.metadata.input);
156
+ }
157
+ if (tool.metadata.output !== undefined) {
158
+ info.outputSchema = toolContractName(tool.metadata.output);
159
+ }
160
+ return Object.freeze(info);
161
+ }
162
+
163
+ }
@@ -0,0 +1,102 @@
1
+ import type { Class } from "../../di";
2
+ import type { JsonObject, JsonValue } from "../semantic";
3
+ import { AgentToolExecutionError } from "../errors";
4
+ import { agentModelJson, bindAgentModel } from "./AgentModelBinding";
5
+
6
+ export interface AgentToolValidationIssue {
7
+ readonly property: string;
8
+ readonly message: string;
9
+ readonly code?: string;
10
+ }
11
+
12
+ export interface AgentToolValidationResult {
13
+ readonly isValid: boolean;
14
+ readonly errors: readonly AgentToolValidationIssue[];
15
+ }
16
+
17
+ export interface AgentToolSchemaValidator {
18
+ validate(instance: object): AgentToolValidationResult | Promise<AgentToolValidationResult>;
19
+ }
20
+
21
+ type ContractResult =
22
+ | { readonly ok: true; readonly value: object }
23
+ | { readonly ok: false; readonly error: { readonly code: string; readonly message: string; readonly details: JsonObject } };
24
+
25
+ /** DTO binding and validation only; execution outcomes belong to the executor. */
26
+ export class ToolContractValidator {
27
+ public async validate(
28
+ contract: Class<object>, value: unknown, direction: "input" | "output",
29
+ toolName: string, validator?: AgentToolSchemaValidator,
30
+ ): Promise<ContractResult> {
31
+ const details = () => ({ toolName, schema: toolContractName(contract), direction });
32
+ let instance: object;
33
+ try {
34
+ if (direction === "output" && typeof value === "object" && value !== null && !Array.isArray(value)) {
35
+ value = agentModelJson(value, "tool.output");
36
+ }
37
+ instance = bindAgentModel(contract, value);
38
+ } catch (error) {
39
+ return { ok: false, error: {
40
+ code: direction === "input" ? "TOOL_INPUT_INVALID" : "TOOL_OUTPUT_INVALID",
41
+ message: toolErrorMessage(error), details: details(),
42
+ } };
43
+ }
44
+ if (!validator) return { ok: true, value: instance };
45
+ let validation: AgentToolValidationResult;
46
+ try {
47
+ const rawValidation = await validator.validate(instance);
48
+ if (!validationResultIsValid(rawValidation)) throw new AgentToolExecutionError("schema validator returned an invalid result.");
49
+ validation = rawValidation;
50
+ } catch (error) {
51
+ return { ok: false, error: {
52
+ code: "TOOL_SCHEMA_VALIDATION_FAILED",
53
+ message: `Tool ${direction} schema validation failed: ${toolErrorMessage(error)}`,
54
+ details: details(),
55
+ } };
56
+ }
57
+ if (!validation.isValid) return { ok: false, error: {
58
+ code: direction === "input" ? "TOOL_INPUT_VALIDATION_FAILED" : "TOOL_OUTPUT_VALIDATION_FAILED",
59
+ message: `Tool "${toolName}" ${direction} failed schema validation.`,
60
+ details: { ...details(), issues: normalizeValidationIssues(validation.errors) },
61
+ } };
62
+ return { ok: true, value: instance };
63
+ }
64
+ }
65
+
66
+ export function toolContractName(model: Class<object>): string {
67
+ return model.name && model.name.trim().length > 0 ? model.name : "<anonymous class>";
68
+ }
69
+
70
+ export function toolErrorMessage(value: unknown): string {
71
+ try {
72
+ return value instanceof Error && typeof value.message === "string" ? value.message : String(value);
73
+ } catch {
74
+ return "Unknown error.";
75
+ }
76
+ }
77
+
78
+ function normalizeValidationIssues(errors: readonly AgentToolValidationIssue[]): JsonValue {
79
+ const issues: JsonValue[] = [];
80
+ for (let index = 0; index < errors.length; index += 1) {
81
+ const error = errors[index] as AgentToolValidationIssue;
82
+ const issue: Record<string, JsonValue> = {
83
+ property: typeof error.property === "string" ? error.property : toolErrorMessage(error.property),
84
+ message: typeof error.message === "string" ? error.message : toolErrorMessage(error.message),
85
+ };
86
+ if (error.code !== undefined) {
87
+ issue.code = toolErrorMessage(error.code);
88
+ }
89
+ issues.push(Object.freeze(issue));
90
+ }
91
+ return Object.freeze(issues);
92
+ }
93
+
94
+ function validationResultIsValid(value: unknown): value is AgentToolValidationResult {
95
+ return (
96
+ typeof value === "object" &&
97
+ value !== null &&
98
+ typeof (value as { isValid?: unknown }).isValid === "boolean" &&
99
+ Array.isArray((value as { errors?: unknown }).errors)
100
+ );
101
+ }
102
+