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,590 @@
1
+ import {
2
+ agentMessage,
3
+ agentModelResponse,
4
+ agentToolCall,
5
+ type AgentContentPart,
6
+ type AgentFinishReason,
7
+ type AgentMessage,
8
+ type AgentModelProvider,
9
+ type AgentModelProviderContext,
10
+ type AgentModelRequest,
11
+ type AgentModelResponse,
12
+ type AgentToolCall,
13
+ type AgentToolContract,
14
+ type JsonObject,
15
+ type JsonValue,
16
+ normalizeJsonValue,
17
+ } from "../../agent";
18
+ import {
19
+ DEFAULT_LLM_REQUEST_TIMEOUT_MS,
20
+ type LlmConnectionOptions,
21
+ type LlmProviderAdapter,
22
+ } from "./llm";
23
+ import { readOpenAiTextStream } from "./openaiTextStream";
24
+
25
+ const DEFAULT_CHAT_COMPLETIONS_PATH = "/chat/completions";
26
+ const DEFAULT_HEALTH_PATH = "/models";
27
+ const DEFAULT_MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
28
+
29
+ export interface OpenAiCompatibleAdapterOptions {
30
+ readonly fetch?: OpenAiCompatibleFetch;
31
+ readonly chatCompletionsPath?: string;
32
+ readonly healthPath?: string;
33
+ readonly healthCheck?: boolean;
34
+ readonly extraHeaders?: Readonly<Record<string, string>>;
35
+ /** Maximum successful provider response size. Defaults to 16 MiB. */
36
+ readonly maxResponseBytes?: number;
37
+ }
38
+
39
+ export type OpenAiCompatibleFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
40
+
41
+ export class OpenAiCompatibleProviderError extends Error {
42
+ public constructor(message: string) {
43
+ super(message);
44
+ this.name = "OpenAiCompatibleProviderError";
45
+ }
46
+ }
47
+
48
+ type OpenAiChatRole = "system" | "user" | "assistant" | "tool";
49
+
50
+ interface OpenAiChatMessage {
51
+ readonly role: OpenAiChatRole;
52
+ readonly content?: string | null;
53
+ readonly tool_call_id?: string;
54
+ readonly tool_calls?: readonly OpenAiToolCall[];
55
+ }
56
+
57
+ interface OpenAiToolDefinition {
58
+ readonly type: "function";
59
+ readonly function: {
60
+ readonly name: string;
61
+ readonly description: string;
62
+ readonly parameters: JsonObject;
63
+ };
64
+ }
65
+
66
+ interface OpenAiToolCall {
67
+ readonly id: string;
68
+ readonly type: "function";
69
+ readonly function: {
70
+ readonly name: string;
71
+ readonly arguments: string;
72
+ };
73
+ }
74
+
75
+ interface OpenAiChatChoice {
76
+ readonly finish_reason?: string;
77
+ readonly message?: {
78
+ readonly role?: string;
79
+ readonly content?: string | null;
80
+ readonly tool_calls?: readonly OpenAiToolCall[];
81
+ };
82
+ }
83
+
84
+ interface OpenAiChatResponse {
85
+ readonly choices?: readonly OpenAiChatChoice[];
86
+ readonly usage?: {
87
+ readonly prompt_tokens?: number;
88
+ readonly completion_tokens?: number;
89
+ readonly total_tokens?: number;
90
+ };
91
+ readonly error?: {
92
+ readonly message?: string;
93
+ };
94
+ }
95
+
96
+ interface ToolNameMapping {
97
+ readonly providerToBazis: ReadonlyMap<string, string>;
98
+ readonly bazisToProvider: ReadonlyMap<string, string>;
99
+ }
100
+
101
+ function stripTrailingSlash(value: string): string {
102
+ return value.replace(/\/+$/, "");
103
+ }
104
+
105
+ function ensureLeadingSlash(value: string): string {
106
+ return value.startsWith("/") ? value : `/${value}`;
107
+ }
108
+
109
+ function errorMessageOf(error: unknown): string {
110
+ try {
111
+ return error instanceof Error && typeof error.message === "string" ? error.message : String(error);
112
+ } catch {
113
+ return "Unknown error.";
114
+ }
115
+ }
116
+
117
+ function cancelBodyBestEffort(body: ReadableStream<Uint8Array> | null | undefined, reason?: unknown): void {
118
+ if (body === null || body === undefined) return;
119
+ // Cleanup is deliberately not part of the provider terminal boundary: a
120
+ // hostile/custom stream may never settle cancel().
121
+ void body.cancel(reason).catch(() => undefined);
122
+ }
123
+
124
+ function shortHash(value: string): string {
125
+ let hash = 2166136261;
126
+ for (let index = 0; index < value.length; index += 1) {
127
+ hash ^= value.charCodeAt(index);
128
+ hash = Math.imul(hash, 16777619);
129
+ }
130
+ return (hash >>> 0).toString(36);
131
+ }
132
+
133
+ function providerToolName(name: string, used: Set<string>): string {
134
+ const replaced = name.replace(/[^a-zA-Z0-9_-]/g, "_");
135
+ const prefixed = /^[a-zA-Z_]/.test(replaced) ? replaced : `tool_${replaced}`;
136
+ const trimmed = prefixed.length <= 64 ? prefixed : `${prefixed.slice(0, 55)}_${shortHash(name)}`;
137
+ if (!used.has(trimmed)) {
138
+ used.add(trimmed);
139
+ return trimmed;
140
+ }
141
+
142
+ const suffix = shortHash(name);
143
+ const base = trimmed.slice(0, Math.max(1, 63 - suffix.length));
144
+ const unique = `${base}_${suffix}`;
145
+ if (used.has(unique)) {
146
+ throw new OpenAiCompatibleProviderError(`Tool name "${name}" collides after OpenAI-compatible normalization.`);
147
+ }
148
+ used.add(unique);
149
+ return unique;
150
+ }
151
+
152
+ function toolNameMapping(tools: readonly AgentToolContract[]): ToolNameMapping {
153
+ const providerToBazis = new Map<string, string>();
154
+ const bazisToProvider = new Map<string, string>();
155
+ const used = new Set<string>();
156
+ for (let index = 0; index < tools.length; index += 1) {
157
+ const tool = tools[index] as AgentToolContract;
158
+ const providerName = providerToolName(tool.name, used);
159
+ providerToBazis.set(providerName, tool.name);
160
+ bazisToProvider.set(tool.name, providerName);
161
+ }
162
+ return Object.freeze({ providerToBazis, bazisToProvider });
163
+ }
164
+
165
+ function schemaForTool(tool: AgentToolContract): JsonObject {
166
+ if (tool.input?.kind === "json-schema") {
167
+ return tool.input.schema;
168
+ }
169
+ return Object.freeze({
170
+ type: "object",
171
+ additionalProperties: true,
172
+ });
173
+ }
174
+
175
+ function openAiTools(tools: readonly AgentToolContract[], mapping: ToolNameMapping): readonly OpenAiToolDefinition[] {
176
+ return Object.freeze(tools.map((tool) => Object.freeze({
177
+ type: "function" as const,
178
+ function: Object.freeze({
179
+ name: mapping.bazisToProvider.get(tool.name) ?? tool.name,
180
+ description: tool.description,
181
+ parameters: schemaForTool(tool),
182
+ }),
183
+ })));
184
+ }
185
+
186
+ function contentText(parts: readonly AgentContentPart[]): string {
187
+ const lines: string[] = [];
188
+ for (let index = 0; index < parts.length; index += 1) {
189
+ const part = parts[index] as AgentContentPart;
190
+ switch (part.kind) {
191
+ case "text":
192
+ lines.push(part.text);
193
+ break;
194
+ case "data":
195
+ lines.push(JSON.stringify({ name: part.name ?? null, value: part.value }));
196
+ break;
197
+ case "tool-result":
198
+ // Provider transcripts contain only the model-facing result contract.
199
+ // Internal runtime metadata, timings and duplicate protocol ids stay
200
+ // inside Bazis and are never sent to an external LLM.
201
+ lines.push(JSON.stringify({
202
+ name: part.result.name,
203
+ status: part.result.status,
204
+ ...(part.result.output !== undefined ? { output: part.result.output } : {}),
205
+ ...(part.result.error !== undefined ? { error: part.result.error } : {}),
206
+ }));
207
+ break;
208
+ case "tool-call":
209
+ // Assistant tool calls are represented by the protocol-level
210
+ // `tool_calls` field, not duplicated into textual content.
211
+ break;
212
+ case "image":
213
+ lines.push(JSON.stringify({ kind: "image", uri: part.uri, mediaType: part.mediaType ?? null, detail: part.detail }));
214
+ break;
215
+ case "file":
216
+ lines.push(JSON.stringify({ kind: "file", uri: part.uri, mediaType: part.mediaType ?? null, name: part.name ?? null }));
217
+ break;
218
+ default:
219
+ break;
220
+ }
221
+ }
222
+ return lines.join("\n");
223
+ }
224
+
225
+ function toOpenAiRole(role: AgentMessage["role"]): OpenAiChatRole {
226
+ if (role === "developer") {
227
+ return "system";
228
+ }
229
+ if (role === "tool") {
230
+ return "tool";
231
+ }
232
+ if (role === "assistant") {
233
+ return "assistant";
234
+ }
235
+ if (role === "system") {
236
+ return "system";
237
+ }
238
+ return "user";
239
+ }
240
+
241
+ function normalizeOpenAiResponse(value: unknown): OpenAiChatResponse {
242
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
243
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response must be a JSON object.");
244
+ }
245
+ return value as OpenAiChatResponse;
246
+ }
247
+
248
+ function finishReasonOf(reason: string | undefined, hasToolCalls: boolean): AgentFinishReason {
249
+ if (hasToolCalls || reason === "tool_calls") {
250
+ return "tool-calls";
251
+ }
252
+ if (reason === undefined || reason === "stop") {
253
+ return "stop";
254
+ }
255
+ if (reason === "length") {
256
+ return "length";
257
+ }
258
+ if (reason === "content_filter") {
259
+ return "content-filter";
260
+ }
261
+ return "error";
262
+ }
263
+
264
+ function parseToolArguments(raw: string, callId: string): JsonValue {
265
+ if (raw.trim().length === 0) {
266
+ return Object.freeze({});
267
+ }
268
+ try {
269
+ return normalizeJsonValue(JSON.parse(raw), `toolCall.${callId}.arguments`);
270
+ } catch (error) {
271
+ throw new OpenAiCompatibleProviderError(`OpenAI-compatible tool arguments for "${callId}" are invalid JSON: ${errorMessageOf(error)}`);
272
+ }
273
+ }
274
+
275
+ function normalizeToolCalls(
276
+ calls: readonly OpenAiToolCall[] | undefined,
277
+ mapping: ToolNameMapping,
278
+ ): readonly AgentToolCall[] {
279
+ if (!calls || calls.length === 0) {
280
+ return Object.freeze([]);
281
+ }
282
+ const out: AgentToolCall[] = [];
283
+ for (let index = 0; index < calls.length; index += 1) {
284
+ const call = calls[index] as OpenAiToolCall;
285
+ if (call.type !== "function") {
286
+ throw new OpenAiCompatibleProviderError(`OpenAI-compatible tool call at index ${index} has an unsupported type.`);
287
+ }
288
+ if (!call.function || typeof call.function.name !== "string" || typeof call.function.arguments !== "string") {
289
+ throw new OpenAiCompatibleProviderError(`OpenAI-compatible tool call at index ${index} is malformed.`);
290
+ }
291
+ const providerName = call.function?.name;
292
+ const name = mapping.providerToBazis.get(providerName) ?? providerName;
293
+ out.push(agentToolCall({
294
+ id: call.id,
295
+ name,
296
+ input: parseToolArguments(call.function?.arguments ?? "", call.id),
297
+ }));
298
+ }
299
+ return Object.freeze(out);
300
+ }
301
+
302
+ function buildUsage(usage: OpenAiChatResponse["usage"]): AgentModelResponse["usage"] | undefined {
303
+ if (!usage) {
304
+ return undefined;
305
+ }
306
+ return Object.freeze({
307
+ ...(usage.prompt_tokens !== undefined ? { inputTokens: usage.prompt_tokens } : {}),
308
+ ...(usage.completion_tokens !== undefined ? { outputTokens: usage.completion_tokens } : {}),
309
+ ...(usage.total_tokens !== undefined ? { totalTokens: usage.total_tokens } : {}),
310
+ });
311
+ }
312
+
313
+ function attachAbortForwarding(source: AbortSignal | undefined, target: AbortController): (() => void) | undefined {
314
+ if (source === undefined) {
315
+ return undefined;
316
+ }
317
+ if (source.aborted) {
318
+ target.abort(source.reason);
319
+ return undefined;
320
+ }
321
+ const abort = () => target.abort(source.reason);
322
+ source.addEventListener("abort", abort, { once: true });
323
+ return () => source.removeEventListener("abort", abort);
324
+ }
325
+
326
+ export class OpenAiCompatibleModelProvider implements AgentModelProvider {
327
+ private readonly lifetime = new AbortController();
328
+ private readonly baseUrl: string;
329
+ private readonly chatCompletionsPath: string;
330
+ private readonly healthPath: string;
331
+ private readonly fetcher: OpenAiCompatibleFetch;
332
+ private readonly headers: Readonly<Record<string, string>>;
333
+ private readonly maxResponseBytes: number;
334
+ private readonly requestTimeoutMs?: number;
335
+
336
+ public constructor(
337
+ private readonly connection: LlmConnectionOptions,
338
+ options: OpenAiCompatibleAdapterOptions = {},
339
+ ) {
340
+ this.baseUrl = stripTrailingSlash(connection.baseUrl);
341
+ this.chatCompletionsPath = ensureLeadingSlash(options.chatCompletionsPath ?? DEFAULT_CHAT_COMPLETIONS_PATH);
342
+ this.healthPath = ensureLeadingSlash(options.healthPath ?? DEFAULT_HEALTH_PATH);
343
+ this.fetcher = options.fetch ?? fetch;
344
+ const configuredTimeout = connection.timeoutMs ?? DEFAULT_LLM_REQUEST_TIMEOUT_MS;
345
+ if (!Number.isSafeInteger(configuredTimeout) || configuredTimeout < 0) {
346
+ throw new OpenAiCompatibleProviderError("timeoutMs must be a non-negative safe integer.");
347
+ }
348
+ this.requestTimeoutMs = configuredTimeout === 0 ? undefined : configuredTimeout;
349
+ if (
350
+ options.maxResponseBytes !== undefined
351
+ && (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes <= 0)
352
+ ) {
353
+ throw new OpenAiCompatibleProviderError("maxResponseBytes must be a positive safe integer.");
354
+ }
355
+ this.maxResponseBytes = options.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES;
356
+ this.headers = Object.freeze({
357
+ "content-type": "application/json",
358
+ authorization: `Bearer ${connection.apiKey}`,
359
+ ...(options.extraHeaders ?? {}),
360
+ });
361
+ }
362
+
363
+ public async complete(request: AgentModelRequest, context: AgentModelProviderContext): Promise<AgentModelResponse> {
364
+ if (request.model !== undefined && request.model !== this.connection.model) {
365
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible request model conflicts with the configured Infra model.");
366
+ }
367
+ const mapping = toolNameMapping(request.tools);
368
+ const body = this.buildBody(request, mapping);
369
+ const onText = (!request.output || request.output.mode === "text") ? context.onTextDelta : undefined;
370
+ if (onText) { body.stream = true; body.stream_options = { include_usage: true }; }
371
+ const raw = await this.request(this.chatCompletionsPath, "POST", body, context.signal, onText, request.tools.length > 0);
372
+ const parsed = normalizeOpenAiResponse(raw);
373
+ const choice = parsed.choices?.[0];
374
+ if (!choice) {
375
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response does not contain choices[0].");
376
+ }
377
+
378
+ const providerToolCalls = choice.message?.tool_calls ?? [];
379
+ const toolCalls = normalizeToolCalls(providerToolCalls, mapping);
380
+ const text = typeof choice.message?.content === "string" ? choice.message.content : "";
381
+ return agentModelResponse({
382
+ invocationId: request.invocationId,
383
+ finishReason: finishReasonOf(choice.finish_reason, toolCalls.length > 0),
384
+ message: text.trim().length > 0 ? agentMessage("assistant", text) : undefined,
385
+ toolCalls,
386
+ usage: buildUsage(parsed.usage),
387
+ });
388
+ }
389
+
390
+ public async ping(signal?: AbortSignal): Promise<boolean> {
391
+ try {
392
+ await this.request(this.healthPath, "GET", undefined, signal);
393
+ return true;
394
+ } catch {
395
+ return false;
396
+ }
397
+ }
398
+
399
+ /** End active requests and reject subsequent calls through this provider. */
400
+ public dispose(): void {
401
+ this.lifetime.abort(new OpenAiCompatibleProviderError("OpenAI-compatible provider is disposed."));
402
+ }
403
+
404
+ private buildBody(request: AgentModelRequest, mapping: ToolNameMapping): Record<string, unknown> {
405
+ const tools = openAiTools(request.tools, mapping);
406
+ const body: Record<string, unknown> = {
407
+ model: this.connection.model,
408
+ messages: this.messages(request.messages, mapping),
409
+ };
410
+ if (tools.length > 0) {
411
+ body.tools = tools;
412
+ body.tool_choice = "auto";
413
+ }
414
+ if (request.temperature !== undefined) {
415
+ body.temperature = request.temperature;
416
+ }
417
+ if (request.maxOutputTokens !== undefined) {
418
+ body.max_tokens = request.maxOutputTokens;
419
+ }
420
+ if (request.output?.mode === "json") {
421
+ const schema = request.output.schema;
422
+ if (schema?.kind === "class") {
423
+ throw new OpenAiCompatibleProviderError(`Output schema "${schema.name}" needs generated JSON Schema metadata for this provider.`);
424
+ }
425
+ body.response_format = schema === undefined ? { type: "json_object" } : {
426
+ type: "json_schema",
427
+ json_schema: {
428
+ name: providerToolName(schema.name, new Set()),
429
+ strict: schema.strict,
430
+ schema: schema.schema,
431
+ ...(request.output.description === undefined ? {} : { description: request.output.description }),
432
+ },
433
+ };
434
+ }
435
+ return body;
436
+ }
437
+
438
+ private messages(messages: readonly AgentMessage[], mapping: ToolNameMapping): readonly OpenAiChatMessage[] {
439
+ const out: OpenAiChatMessage[] = [];
440
+ for (let index = 0; index < messages.length; index += 1) {
441
+ const message = messages[index] as AgentMessage;
442
+ if (message.role === "tool") {
443
+ out.push(Object.freeze({
444
+ role: "tool",
445
+ tool_call_id: message.toolCallId,
446
+ content: contentText(message.content),
447
+ }));
448
+ continue;
449
+ }
450
+
451
+ if (message.role === "assistant") {
452
+ const toolCalls = message.content
453
+ .filter((part) => part.kind === "tool-call")
454
+ .map((part) => {
455
+ const providerName = mapping.bazisToProvider.get(part.call.name);
456
+ if (providerName === undefined) {
457
+ throw new OpenAiCompatibleProviderError(
458
+ `Assistant transcript references tool "${part.call.name}" which is absent from the request contract.`,
459
+ );
460
+ }
461
+ return Object.freeze({
462
+ id: part.call.id,
463
+ type: "function" as const,
464
+ function: Object.freeze({
465
+ name: providerName,
466
+ arguments: JSON.stringify(part.call.input),
467
+ }),
468
+ });
469
+ });
470
+ const content = contentText(message.content);
471
+ out.push(Object.freeze({
472
+ role: "assistant",
473
+ content: content.length > 0 ? content : null,
474
+ ...(toolCalls.length > 0 ? { tool_calls: Object.freeze(toolCalls) } : {}),
475
+ }));
476
+ continue;
477
+ }
478
+
479
+ out.push(Object.freeze({
480
+ role: toOpenAiRole(message.role),
481
+ content: contentText(message.content),
482
+ }));
483
+ }
484
+ return Object.freeze(out);
485
+ }
486
+
487
+ private async request(path: string, method: "GET" | "POST", body?: unknown, signal?: AbortSignal,
488
+ onText?: (text: string) => void, allowTools = false): Promise<unknown> {
489
+ const abort = new AbortController();
490
+ const detach = attachAbortForwarding(signal ? AbortSignal.any([signal, this.lifetime.signal]) : this.lifetime.signal, abort);
491
+ const timeout = this.requestTimeoutMs === undefined
492
+ ? undefined
493
+ : setTimeout(() => abort.abort(new Error("OpenAI-compatible request timed out.")), this.requestTimeoutMs);
494
+ try {
495
+ abort.signal.throwIfAborted();
496
+ const response = await this.fetcher(`${this.baseUrl}${path}`, {
497
+ method,
498
+ headers: this.headers,
499
+ body: body === undefined ? undefined : JSON.stringify(body),
500
+ signal: abort.signal,
501
+ });
502
+ if (!response.ok) {
503
+ // Cancel the provider-controlled body without exposing it: error bodies
504
+ // may echo prompts, credentials or tenant data.
505
+ cancelBodyBestEffort(response.body);
506
+ throw new OpenAiCompatibleProviderError(
507
+ `OpenAI-compatible ${method} ${path} failed with HTTP ${response.status}.`,
508
+ );
509
+ }
510
+ if (response.status === 204) {
511
+ return {};
512
+ }
513
+ // Keep timeout/caller abort forwarding installed until the body has been
514
+ // fully consumed; `return promise` would run finally immediately.
515
+ if (onText && response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() === "text/event-stream") {
516
+ return await readOpenAiTextStream(response, abort.signal, this.maxResponseBytes, onText, allowTools);
517
+ }
518
+ return await this.readJsonResponse(response, abort.signal);
519
+ } finally {
520
+ detach?.();
521
+ if (timeout !== undefined) {
522
+ clearTimeout(timeout);
523
+ }
524
+ }
525
+ }
526
+
527
+ private async readJsonResponse(response: Response, signal: AbortSignal): Promise<unknown> {
528
+ const advertised = response.headers.get("content-length");
529
+ if (advertised !== null) {
530
+ const bytes = Number(advertised);
531
+ if (Number.isFinite(bytes) && bytes > this.maxResponseBytes) {
532
+ cancelBodyBestEffort(response.body);
533
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response exceeds maxResponseBytes.");
534
+ }
535
+ }
536
+ if (response.body === null) {
537
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response body is empty.");
538
+ }
539
+
540
+ const reader = response.body.getReader();
541
+ const chunks: Uint8Array[] = [];
542
+ let total = 0;
543
+ const cancelReader = () => { void reader.cancel(signal.reason).catch(() => undefined); };
544
+ if (signal.aborted) cancelReader();
545
+ else signal.addEventListener("abort", cancelReader, { once: true });
546
+ try {
547
+ while (true) {
548
+ const item = await reader.read();
549
+ if (signal.aborted) throw new OpenAiCompatibleProviderError("OpenAI-compatible request was aborted.");
550
+ if (item.done) break;
551
+ total += item.value.byteLength;
552
+ if (total > this.maxResponseBytes) {
553
+ void reader.cancel().catch(() => undefined);
554
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response exceeds maxResponseBytes.");
555
+ }
556
+ chunks.push(item.value);
557
+ }
558
+ } finally {
559
+ signal.removeEventListener("abort", cancelReader);
560
+ reader.releaseLock();
561
+ }
562
+
563
+ const bytes = new Uint8Array(total);
564
+ let offset = 0;
565
+ for (const chunk of chunks) {
566
+ bytes.set(chunk, offset);
567
+ offset += chunk.byteLength;
568
+ }
569
+ try {
570
+ return JSON.parse(new TextDecoder().decode(bytes)) as unknown;
571
+ } catch {
572
+ throw new OpenAiCompatibleProviderError("OpenAI-compatible response contains invalid JSON.");
573
+ }
574
+ }
575
+ }
576
+
577
+ export function openAiCompatibleAdapter(options: OpenAiCompatibleAdapterOptions = {}): LlmProviderAdapter {
578
+ const healthCheckEnabled = options.healthCheck ?? true;
579
+ return {
580
+ create(connection) {
581
+ return new OpenAiCompatibleModelProvider(connection, options);
582
+ },
583
+ dispose(provider) {
584
+ if (provider instanceof OpenAiCompatibleModelProvider) provider.dispose();
585
+ },
586
+ healthCheck: healthCheckEnabled
587
+ ? (provider, signal) => provider instanceof OpenAiCompatibleModelProvider && provider.ping(signal)
588
+ : undefined,
589
+ };
590
+ }