@sixthsummit/ship-api 0.0.0-stage → 4.1.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 (556) hide show
  1. package/CHANGELOG.md +605 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +4 -0
  4. package/README.md +58 -2
  5. package/cli/commands/add.js +537 -0
  6. package/cli/commands/contract.js +2 -0
  7. package/cli/commands/create.js +250 -0
  8. package/cli/commands/dev.js +227 -0
  9. package/cli/commands/doctor.js +286 -0
  10. package/cli/commands/generate.js +937 -0
  11. package/cli/commands/graph.js +2 -0
  12. package/cli/commands/migrate-orm.js +1171 -0
  13. package/cli/commands/update.js +37 -0
  14. package/cli/ship-api.js +285 -0
  15. package/lib/app/auth/AuthProvider.d.ts +91 -0
  16. package/lib/app/auth/AuthProvider.d.ts.map +1 -0
  17. package/lib/app/auth/AuthProvider.js +13 -0
  18. package/lib/app/auth/AuthProvider.js.map +1 -0
  19. package/lib/app/auth/adapters/firebase.d.ts +79 -0
  20. package/lib/app/auth/adapters/firebase.d.ts.map +1 -0
  21. package/lib/app/auth/adapters/firebase.js +122 -0
  22. package/lib/app/auth/adapters/firebase.js.map +1 -0
  23. package/lib/app/auth/adapters/jwtCookie.d.ts +55 -0
  24. package/lib/app/auth/adapters/jwtCookie.d.ts.map +1 -0
  25. package/lib/app/auth/adapters/jwtCookie.js +120 -0
  26. package/lib/app/auth/adapters/jwtCookie.js.map +1 -0
  27. package/lib/app/auth/index.d.ts +8 -0
  28. package/lib/app/auth/index.d.ts.map +1 -0
  29. package/lib/app/auth/index.js +7 -0
  30. package/lib/app/auth/index.js.map +1 -0
  31. package/lib/app/auth/jwt/AuthFlow.d.ts +94 -0
  32. package/lib/app/auth/jwt/AuthFlow.d.ts.map +1 -0
  33. package/lib/app/auth/jwt/AuthFlow.js +127 -0
  34. package/lib/app/auth/jwt/AuthFlow.js.map +1 -0
  35. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts +80 -0
  36. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts.map +1 -0
  37. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js +134 -0
  38. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js.map +1 -0
  39. package/lib/app/auth/jwt/JwtSigner.d.ts +123 -0
  40. package/lib/app/auth/jwt/JwtSigner.d.ts.map +1 -0
  41. package/lib/app/auth/jwt/JwtSigner.js +118 -0
  42. package/lib/app/auth/jwt/JwtSigner.js.map +1 -0
  43. package/lib/app/auth/jwt/RefreshTokenStore.d.ts +97 -0
  44. package/lib/app/auth/jwt/RefreshTokenStore.d.ts.map +1 -0
  45. package/lib/app/auth/jwt/RefreshTokenStore.js +122 -0
  46. package/lib/app/auth/jwt/RefreshTokenStore.js.map +1 -0
  47. package/lib/app/auth/permissionDefinition.d.ts +20 -0
  48. package/lib/app/auth/permissionDefinition.d.ts.map +1 -0
  49. package/lib/app/auth/permissionDefinition.js +2 -0
  50. package/lib/app/auth/permissionDefinition.js.map +1 -0
  51. package/lib/app/context/RequestContext.d.ts +59 -0
  52. package/lib/app/context/RequestContext.d.ts.map +1 -0
  53. package/lib/app/context/RequestContext.js +25 -0
  54. package/lib/app/context/RequestContext.js.map +1 -0
  55. package/lib/app/db/QueryOptions.d.ts +82 -0
  56. package/lib/app/db/QueryOptions.d.ts.map +1 -0
  57. package/lib/app/db/QueryOptions.js +37 -0
  58. package/lib/app/db/QueryOptions.js.map +1 -0
  59. package/lib/app/db/baseFields.d.ts +60 -0
  60. package/lib/app/db/baseFields.d.ts.map +1 -0
  61. package/lib/app/db/baseFields.js +54 -0
  62. package/lib/app/db/baseFields.js.map +1 -0
  63. package/lib/app/db/buildWhere.d.ts +22 -0
  64. package/lib/app/db/buildWhere.d.ts.map +1 -0
  65. package/lib/app/db/buildWhere.js +75 -0
  66. package/lib/app/db/buildWhere.js.map +1 -0
  67. package/lib/app/db/client.d.ts +111 -0
  68. package/lib/app/db/client.d.ts.map +1 -0
  69. package/lib/app/db/client.js +99 -0
  70. package/lib/app/db/client.js.map +1 -0
  71. package/lib/app/db/tenantScoped.d.ts +59 -0
  72. package/lib/app/db/tenantScoped.d.ts.map +1 -0
  73. package/lib/app/db/tenantScoped.js +54 -0
  74. package/lib/app/db/tenantScoped.js.map +1 -0
  75. package/lib/app/db/transaction.d.ts +58 -0
  76. package/lib/app/db/transaction.d.ts.map +1 -0
  77. package/lib/app/db/transaction.js +106 -0
  78. package/lib/app/db/transaction.js.map +1 -0
  79. package/lib/app/health/HealthCheck.d.ts +121 -0
  80. package/lib/app/health/HealthCheck.d.ts.map +1 -0
  81. package/lib/app/health/HealthCheck.js +151 -0
  82. package/lib/app/health/HealthCheck.js.map +1 -0
  83. package/lib/app/health/redisHealthCheck.d.ts +14 -0
  84. package/lib/app/health/redisHealthCheck.d.ts.map +1 -0
  85. package/lib/app/health/redisHealthCheck.js +21 -0
  86. package/lib/app/health/redisHealthCheck.js.map +1 -0
  87. package/lib/app/lifecycle/Bootstrapper.d.ts +92 -0
  88. package/lib/app/lifecycle/Bootstrapper.d.ts.map +1 -0
  89. package/lib/app/lifecycle/Bootstrapper.js +99 -0
  90. package/lib/app/lifecycle/Bootstrapper.js.map +1 -0
  91. package/lib/app/registry/routes.d.ts +89 -0
  92. package/lib/app/registry/routes.d.ts.map +1 -0
  93. package/lib/app/registry/routes.js +72 -0
  94. package/lib/app/registry/routes.js.map +1 -0
  95. package/lib/app/services/DrizzleEntityService.d.ts +123 -0
  96. package/lib/app/services/DrizzleEntityService.d.ts.map +1 -0
  97. package/lib/app/services/DrizzleEntityService.js +342 -0
  98. package/lib/app/services/DrizzleEntityService.js.map +1 -0
  99. package/lib/app/services/RedisProvider.d.ts +52 -0
  100. package/lib/app/services/RedisProvider.d.ts.map +1 -0
  101. package/lib/app/services/RedisProvider.js +75 -0
  102. package/lib/app/services/RedisProvider.js.map +1 -0
  103. package/lib/app/services/cache/Cache.d.ts +70 -0
  104. package/lib/app/services/cache/Cache.d.ts.map +1 -0
  105. package/lib/app/services/cache/Cache.js +18 -0
  106. package/lib/app/services/cache/Cache.js.map +1 -0
  107. package/lib/app/services/cache/InMemoryCache.d.ts +35 -0
  108. package/lib/app/services/cache/InMemoryCache.d.ts.map +1 -0
  109. package/lib/app/services/cache/InMemoryCache.js +76 -0
  110. package/lib/app/services/cache/InMemoryCache.js.map +1 -0
  111. package/lib/app/services/cache/RedisCache.d.ts +99 -0
  112. package/lib/app/services/cache/RedisCache.d.ts.map +1 -0
  113. package/lib/app/services/cache/RedisCache.js +150 -0
  114. package/lib/app/services/cache/RedisCache.js.map +1 -0
  115. package/lib/app/services/cache/cached.d.ts +30 -0
  116. package/lib/app/services/cache/cached.d.ts.map +1 -0
  117. package/lib/app/services/cache/cached.js +38 -0
  118. package/lib/app/services/cache/cached.js.map +1 -0
  119. package/lib/app/services/cache/index.d.ts +5 -0
  120. package/lib/app/services/cache/index.d.ts.map +1 -0
  121. package/lib/app/services/cache/index.js +4 -0
  122. package/lib/app/services/cache/index.js.map +1 -0
  123. package/lib/app/services/cron/defineCron.d.ts +57 -0
  124. package/lib/app/services/cron/defineCron.d.ts.map +1 -0
  125. package/lib/app/services/cron/defineCron.js +15 -0
  126. package/lib/app/services/cron/defineCron.js.map +1 -0
  127. package/lib/app/services/cron/index.d.ts +2 -0
  128. package/lib/app/services/cron/index.d.ts.map +1 -0
  129. package/lib/app/services/cron/index.js +2 -0
  130. package/lib/app/services/cron/index.js.map +1 -0
  131. package/lib/app/services/hooks/LifecycleHooks.d.ts +61 -0
  132. package/lib/app/services/hooks/LifecycleHooks.d.ts.map +1 -0
  133. package/lib/app/services/hooks/LifecycleHooks.js +85 -0
  134. package/lib/app/services/hooks/LifecycleHooks.js.map +1 -0
  135. package/lib/app/services/jobs/JobsManager.d.ts +67 -0
  136. package/lib/app/services/jobs/JobsManager.d.ts.map +1 -0
  137. package/lib/app/services/jobs/JobsManager.js +121 -0
  138. package/lib/app/services/jobs/JobsManager.js.map +1 -0
  139. package/lib/app/services/jobs/bullBoard.d.ts +72 -0
  140. package/lib/app/services/jobs/bullBoard.d.ts.map +1 -0
  141. package/lib/app/services/jobs/bullBoard.js +96 -0
  142. package/lib/app/services/jobs/bullBoard.js.map +1 -0
  143. package/lib/app/services/jobs/defineJob.d.ts +81 -0
  144. package/lib/app/services/jobs/defineJob.d.ts.map +1 -0
  145. package/lib/app/services/jobs/defineJob.js +49 -0
  146. package/lib/app/services/jobs/defineJob.js.map +1 -0
  147. package/lib/app/services/jobs/index.d.ts +4 -0
  148. package/lib/app/services/jobs/index.d.ts.map +1 -0
  149. package/lib/app/services/jobs/index.js +4 -0
  150. package/lib/app/services/jobs/index.js.map +1 -0
  151. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts +23 -0
  152. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts.map +1 -0
  153. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js +51 -0
  154. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js.map +1 -0
  155. package/lib/app/services/rateLimit/RateLimitBackend.d.ts +41 -0
  156. package/lib/app/services/rateLimit/RateLimitBackend.d.ts.map +1 -0
  157. package/lib/app/services/rateLimit/RateLimitBackend.js +19 -0
  158. package/lib/app/services/rateLimit/RateLimitBackend.js.map +1 -0
  159. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts +16 -0
  160. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts.map +1 -0
  161. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js +80 -0
  162. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js.map +1 -0
  163. package/lib/app/services/rateLimit/index.d.ts +4 -0
  164. package/lib/app/services/rateLimit/index.d.ts.map +1 -0
  165. package/lib/app/services/rateLimit/index.js +3 -0
  166. package/lib/app/services/rateLimit/index.js.map +1 -0
  167. package/lib/app/services/storage/DiskStorageAdapter.d.ts +62 -0
  168. package/lib/app/services/storage/DiskStorageAdapter.d.ts.map +1 -0
  169. package/lib/app/services/storage/DiskStorageAdapter.js +295 -0
  170. package/lib/app/services/storage/DiskStorageAdapter.js.map +1 -0
  171. package/lib/app/services/storage/GCSStorageAdapter.d.ts +44 -0
  172. package/lib/app/services/storage/GCSStorageAdapter.d.ts.map +1 -0
  173. package/lib/app/services/storage/GCSStorageAdapter.js +133 -0
  174. package/lib/app/services/storage/GCSStorageAdapter.js.map +1 -0
  175. package/lib/app/services/storage/S3StorageAdapter.d.ts +57 -0
  176. package/lib/app/services/storage/S3StorageAdapter.d.ts.map +1 -0
  177. package/lib/app/services/storage/S3StorageAdapter.js +162 -0
  178. package/lib/app/services/storage/S3StorageAdapter.js.map +1 -0
  179. package/lib/app/services/storage/StorageService.d.ts +88 -0
  180. package/lib/app/services/storage/StorageService.d.ts.map +1 -0
  181. package/lib/app/services/storage/StorageService.js +18 -0
  182. package/lib/app/services/storage/StorageService.js.map +1 -0
  183. package/lib/app/services/storage/index.d.ts +5 -0
  184. package/lib/app/services/storage/index.d.ts.map +1 -0
  185. package/lib/app/services/storage/index.js +4 -0
  186. package/lib/app/services/storage/index.js.map +1 -0
  187. package/lib/app/utils/ContextValidators.d.ts +46 -0
  188. package/lib/app/utils/ContextValidators.d.ts.map +1 -0
  189. package/lib/app/utils/ContextValidators.js +81 -0
  190. package/lib/app/utils/ContextValidators.js.map +1 -0
  191. package/lib/app/utils/defineEnv.d.ts +80 -0
  192. package/lib/app/utils/defineEnv.d.ts.map +1 -0
  193. package/lib/app/utils/defineEnv.js +95 -0
  194. package/lib/app/utils/defineEnv.js.map +1 -0
  195. package/lib/client.d.ts +139 -0
  196. package/lib/client.d.ts.map +1 -0
  197. package/lib/client.js +98 -0
  198. package/lib/client.js.map +1 -0
  199. package/lib/contract/application.d.ts +3 -0
  200. package/lib/contract/application.d.ts.map +1 -0
  201. package/lib/contract/application.js +2 -0
  202. package/lib/contract/application.js.map +1 -0
  203. package/lib/contract/client.d.ts +3 -0
  204. package/lib/contract/client.d.ts.map +1 -0
  205. package/lib/contract/client.js +3 -0
  206. package/lib/contract/client.js.map +1 -0
  207. package/lib/contract/index.d.ts +3 -0
  208. package/lib/contract/index.d.ts.map +1 -0
  209. package/lib/contract/index.js +3 -0
  210. package/lib/contract/index.js.map +1 -0
  211. package/lib/contract/manifest.d.ts +3 -0
  212. package/lib/contract/manifest.d.ts.map +1 -0
  213. package/lib/contract/manifest.js +2 -0
  214. package/lib/contract/manifest.js.map +1 -0
  215. package/lib/contract/openapi.d.ts +3 -0
  216. package/lib/contract/openapi.d.ts.map +1 -0
  217. package/lib/contract/openapi.js +3 -0
  218. package/lib/contract/openapi.js.map +1 -0
  219. package/lib/contract/project.d.ts +3 -0
  220. package/lib/contract/project.d.ts.map +1 -0
  221. package/lib/contract/project.js +3 -0
  222. package/lib/contract/project.js.map +1 -0
  223. package/lib/contract/schema.d.ts +3 -0
  224. package/lib/contract/schema.d.ts.map +1 -0
  225. package/lib/contract/schema.js +3 -0
  226. package/lib/contract/schema.js.map +1 -0
  227. package/lib/drizzle/index.d.ts +3 -0
  228. package/lib/drizzle/index.d.ts.map +1 -0
  229. package/lib/drizzle/index.js +3 -0
  230. package/lib/drizzle/index.js.map +1 -0
  231. package/lib/hono/auth.d.ts +6 -0
  232. package/lib/hono/auth.d.ts.map +1 -0
  233. package/lib/hono/auth.js +54 -0
  234. package/lib/hono/auth.js.map +1 -0
  235. package/lib/hono/index.d.ts +4 -0
  236. package/lib/hono/index.d.ts.map +1 -0
  237. package/lib/hono/index.js +4 -0
  238. package/lib/hono/index.js.map +1 -0
  239. package/lib/http/app/createApp.d.ts +132 -0
  240. package/lib/http/app/createApp.d.ts.map +1 -0
  241. package/lib/http/app/createApp.js +215 -0
  242. package/lib/http/app/createApp.js.map +1 -0
  243. package/lib/http/app/devRoutes.d.ts +31 -0
  244. package/lib/http/app/devRoutes.d.ts.map +1 -0
  245. package/lib/http/app/devRoutes.js +145 -0
  246. package/lib/http/app/devRoutes.js.map +1 -0
  247. package/lib/http/app/errors.d.ts +45 -0
  248. package/lib/http/app/errors.d.ts.map +1 -0
  249. package/lib/http/app/errors.js +93 -0
  250. package/lib/http/app/errors.js.map +1 -0
  251. package/lib/http/app/health.d.ts +66 -0
  252. package/lib/http/app/health.d.ts.map +1 -0
  253. package/lib/http/app/health.js +104 -0
  254. package/lib/http/app/health.js.map +1 -0
  255. package/lib/http/errors/AppError.d.ts +10 -0
  256. package/lib/http/errors/AppError.d.ts.map +1 -0
  257. package/lib/http/errors/AppError.js +19 -0
  258. package/lib/http/errors/AppError.js.map +1 -0
  259. package/lib/http/errors/AuthenticationError.d.ts +8 -0
  260. package/lib/http/errors/AuthenticationError.d.ts.map +1 -0
  261. package/lib/http/errors/AuthenticationError.js +10 -0
  262. package/lib/http/errors/AuthenticationError.js.map +1 -0
  263. package/lib/http/errors/AuthorizationError.d.ts +8 -0
  264. package/lib/http/errors/AuthorizationError.d.ts.map +1 -0
  265. package/lib/http/errors/AuthorizationError.js +10 -0
  266. package/lib/http/errors/AuthorizationError.js.map +1 -0
  267. package/lib/http/errors/BadRequestError.d.ts +8 -0
  268. package/lib/http/errors/BadRequestError.d.ts.map +1 -0
  269. package/lib/http/errors/BadRequestError.js +10 -0
  270. package/lib/http/errors/BadRequestError.js.map +1 -0
  271. package/lib/http/errors/ConflictError.d.ts +8 -0
  272. package/lib/http/errors/ConflictError.d.ts.map +1 -0
  273. package/lib/http/errors/ConflictError.js +10 -0
  274. package/lib/http/errors/ConflictError.js.map +1 -0
  275. package/lib/http/errors/InternalServerError.d.ts +8 -0
  276. package/lib/http/errors/InternalServerError.d.ts.map +1 -0
  277. package/lib/http/errors/InternalServerError.js +10 -0
  278. package/lib/http/errors/InternalServerError.js.map +1 -0
  279. package/lib/http/errors/NotFoundError.d.ts +8 -0
  280. package/lib/http/errors/NotFoundError.d.ts.map +1 -0
  281. package/lib/http/errors/NotFoundError.js +10 -0
  282. package/lib/http/errors/NotFoundError.js.map +1 -0
  283. package/lib/http/errors/RateLimitError.d.ts +13 -0
  284. package/lib/http/errors/RateLimitError.d.ts.map +1 -0
  285. package/lib/http/errors/RateLimitError.js +16 -0
  286. package/lib/http/errors/RateLimitError.js.map +1 -0
  287. package/lib/http/errors/ServiceUnavailableError.d.ts +8 -0
  288. package/lib/http/errors/ServiceUnavailableError.d.ts.map +1 -0
  289. package/lib/http/errors/ServiceUnavailableError.js +10 -0
  290. package/lib/http/errors/ServiceUnavailableError.js.map +1 -0
  291. package/lib/http/errors/ValidationError.d.ts +9 -0
  292. package/lib/http/errors/ValidationError.d.ts.map +1 -0
  293. package/lib/http/errors/ValidationError.js +12 -0
  294. package/lib/http/errors/ValidationError.js.map +1 -0
  295. package/lib/http/errors/index.d.ts +11 -0
  296. package/lib/http/errors/index.d.ts.map +1 -0
  297. package/lib/http/errors/index.js +12 -0
  298. package/lib/http/errors/index.js.map +1 -0
  299. package/lib/http/middleware/apiKey.d.ts +9 -0
  300. package/lib/http/middleware/apiKey.d.ts.map +1 -0
  301. package/lib/http/middleware/apiKey.js +71 -0
  302. package/lib/http/middleware/apiKey.js.map +1 -0
  303. package/lib/http/middleware/csrf.d.ts +63 -0
  304. package/lib/http/middleware/csrf.d.ts.map +1 -0
  305. package/lib/http/middleware/csrf.js +169 -0
  306. package/lib/http/middleware/csrf.js.map +1 -0
  307. package/lib/http/middleware/httpLogger.d.ts +39 -0
  308. package/lib/http/middleware/httpLogger.d.ts.map +1 -0
  309. package/lib/http/middleware/httpLogger.js +118 -0
  310. package/lib/http/middleware/httpLogger.js.map +1 -0
  311. package/lib/http/middleware/idempotency.d.ts +48 -0
  312. package/lib/http/middleware/idempotency.d.ts.map +1 -0
  313. package/lib/http/middleware/idempotency.js +180 -0
  314. package/lib/http/middleware/idempotency.js.map +1 -0
  315. package/lib/http/middleware/rateLimit.d.ts +105 -0
  316. package/lib/http/middleware/rateLimit.d.ts.map +1 -0
  317. package/lib/http/middleware/rateLimit.js +84 -0
  318. package/lib/http/middleware/rateLimit.js.map +1 -0
  319. package/lib/http/middleware/requireAuth.d.ts +58 -0
  320. package/lib/http/middleware/requireAuth.d.ts.map +1 -0
  321. package/lib/http/middleware/requireAuth.js +63 -0
  322. package/lib/http/middleware/requireAuth.js.map +1 -0
  323. package/lib/http/middleware/requirePermission.d.ts +23 -0
  324. package/lib/http/middleware/requirePermission.d.ts.map +1 -0
  325. package/lib/http/middleware/requirePermission.js +50 -0
  326. package/lib/http/middleware/requirePermission.js.map +1 -0
  327. package/lib/http/middleware/resolveTenant.d.ts +41 -0
  328. package/lib/http/middleware/resolveTenant.d.ts.map +1 -0
  329. package/lib/http/middleware/resolveTenant.js +17 -0
  330. package/lib/http/middleware/resolveTenant.js.map +1 -0
  331. package/lib/http/streaming/sse.d.ts +31 -0
  332. package/lib/http/streaming/sse.d.ts.map +1 -0
  333. package/lib/http/streaming/sse.js +11 -0
  334. package/lib/http/streaming/sse.js.map +1 -0
  335. package/lib/http/streaming/streamLLM.d.ts +94 -0
  336. package/lib/http/streaming/streamLLM.d.ts.map +1 -0
  337. package/lib/http/streaming/streamLLM.js +94 -0
  338. package/lib/http/streaming/streamLLM.js.map +1 -0
  339. package/lib/http/utils/authCookies.d.ts +74 -0
  340. package/lib/http/utils/authCookies.d.ts.map +1 -0
  341. package/lib/http/utils/authCookies.js +102 -0
  342. package/lib/http/utils/authCookies.js.map +1 -0
  343. package/lib/http/utils/clientIp.d.ts +85 -0
  344. package/lib/http/utils/clientIp.d.ts.map +1 -0
  345. package/lib/http/utils/clientIp.js +249 -0
  346. package/lib/http/utils/clientIp.js.map +1 -0
  347. package/lib/http/utils/index.d.ts +4 -0
  348. package/lib/http/utils/index.d.ts.map +1 -0
  349. package/lib/http/utils/index.js +5 -0
  350. package/lib/http/utils/index.js.map +1 -0
  351. package/lib/http/utils/metaTags.d.ts +49 -0
  352. package/lib/http/utils/metaTags.d.ts.map +1 -0
  353. package/lib/http/utils/metaTags.js +32 -0
  354. package/lib/http/utils/metaTags.js.map +1 -0
  355. package/lib/http/utils/publicSuffix.d.ts +34 -0
  356. package/lib/http/utils/publicSuffix.d.ts.map +1 -0
  357. package/lib/http/utils/publicSuffix.js +276 -0
  358. package/lib/http/utils/publicSuffix.js.map +1 -0
  359. package/lib/http/utils/uploads.d.ts +92 -0
  360. package/lib/http/utils/uploads.d.ts.map +1 -0
  361. package/lib/http/utils/uploads.js +126 -0
  362. package/lib/http/utils/uploads.js.map +1 -0
  363. package/lib/http/utils/validate.d.ts +41 -0
  364. package/lib/http/utils/validate.d.ts.map +1 -0
  365. package/lib/http/utils/validate.js +55 -0
  366. package/lib/http/utils/validate.js.map +1 -0
  367. package/lib/http/utils/webhooks.d.ts +63 -0
  368. package/lib/http/utils/webhooks.d.ts.map +1 -0
  369. package/lib/http/utils/webhooks.js +133 -0
  370. package/lib/http/utils/webhooks.js.map +1 -0
  371. package/lib/http/ws/auth.d.ts +46 -0
  372. package/lib/http/ws/auth.d.ts.map +1 -0
  373. package/lib/http/ws/auth.js +123 -0
  374. package/lib/http/ws/auth.js.map +1 -0
  375. package/lib/index.d.ts +80 -0
  376. package/lib/index.d.ts.map +1 -0
  377. package/lib/index.js +61 -0
  378. package/lib/index.js.map +1 -0
  379. package/lib/kernel/index.d.ts +3 -0
  380. package/lib/kernel/index.d.ts.map +1 -0
  381. package/lib/kernel/index.js +3 -0
  382. package/lib/kernel/index.js.map +1 -0
  383. package/lib/libraries/.gitkeep +0 -0
  384. package/lib/libraries/ai/CHANGELOG.md +17 -0
  385. package/lib/libraries/ai/README.md +164 -0
  386. package/lib/libraries/ai/adapters/AnthropicAdapter.ts +382 -0
  387. package/lib/libraries/ai/adapters/LLMProvider.ts +76 -0
  388. package/lib/libraries/ai/adapters/OpenAIAdapter.ts +466 -0
  389. package/lib/libraries/ai/experimental/index.ts +20 -0
  390. package/lib/libraries/ai/index.ts +128 -0
  391. package/lib/libraries/ai/library.json +19 -0
  392. package/lib/libraries/ai/loop/agentLoop.ts +377 -0
  393. package/lib/libraries/ai/prompts/definePrompt.ts +0 -0
  394. package/lib/libraries/ai/rag/retrieveAndAnswer.ts +177 -0
  395. package/lib/libraries/ai/streaming/streamLLM.ts +94 -0
  396. package/lib/libraries/ai/structured/completeStructured.ts +143 -0
  397. package/lib/libraries/ai/tokens/Tokenizer.ts +216 -0
  398. package/lib/libraries/ai/tools/defineTool.ts +208 -0
  399. package/lib/libraries/ai/types.ts +260 -0
  400. package/lib/libraries/chunking/ChunkingService.ts +103 -0
  401. package/lib/libraries/chunking/README.md +104 -0
  402. package/lib/libraries/chunking/docs/api-reference.md +549 -0
  403. package/lib/libraries/chunking/docs/best-practices.md +321 -0
  404. package/lib/libraries/chunking/docs/code-organization.md +538 -0
  405. package/lib/libraries/chunking/docs/configuration.md +418 -0
  406. package/lib/libraries/chunking/docs/index.md +236 -0
  407. package/lib/libraries/chunking/docs/quick-start.md +298 -0
  408. package/lib/libraries/chunking/docs/strategies.md +407 -0
  409. package/lib/libraries/chunking/docs/summary.md +258 -0
  410. package/lib/libraries/chunking/docs/troubleshooting.md +527 -0
  411. package/lib/libraries/chunking/index.ts +17 -0
  412. package/lib/libraries/chunking/library.json +16 -0
  413. package/lib/libraries/chunking/strategies/ChunkingStrategy.ts +13 -0
  414. package/lib/libraries/chunking/strategies/FixedLengthChunkingStrategy.ts +88 -0
  415. package/lib/libraries/chunking/strategies/SemanticChunkingStrategy.ts +389 -0
  416. package/lib/libraries/chunking/strategies/SlidingWindowChunkingStrategy.ts +258 -0
  417. package/lib/libraries/chunking/types/index.ts +63 -0
  418. package/lib/libraries/email/EmailService.ts +591 -0
  419. package/lib/libraries/email/README.md +777 -0
  420. package/lib/libraries/email/TemplateRegistry.ts +148 -0
  421. package/lib/libraries/email/TemplateRenderer.ts +273 -0
  422. package/lib/libraries/email/index.ts +4 -0
  423. package/lib/libraries/email/initializeEmailService.ts +60 -0
  424. package/lib/libraries/email/library.json +12 -0
  425. package/lib/libraries/email/types/EmailAddress.ts +4 -0
  426. package/lib/libraries/email/types/EmailAttachment.ts +11 -0
  427. package/lib/libraries/email/types/EmailTag.ts +9 -0
  428. package/lib/libraries/email/types/EmailTemplate.ts +124 -0
  429. package/lib/libraries/email/types/SendBatchEmailsOptions.ts +9 -0
  430. package/lib/libraries/email/types/SendBatchEmailsResult.ts +9 -0
  431. package/lib/libraries/email/types/SendEmailOptions.ts +33 -0
  432. package/lib/libraries/email/types/SendEmailResult.ts +9 -0
  433. package/lib/libraries/email/types/index.ts +8 -0
  434. package/lib/libraries/weaviate/QueryBuilder.ts +292 -0
  435. package/lib/libraries/weaviate/README.md +284 -0
  436. package/lib/libraries/weaviate/Weaviate.ts +1419 -0
  437. package/lib/libraries/weaviate/WeaviateConfig.ts +268 -0
  438. package/lib/libraries/weaviate/docs/.gitkeep +1 -0
  439. package/lib/libraries/weaviate/docs/API_REFERENCE.md +1067 -0
  440. package/lib/libraries/weaviate/docs/CONFIGURATION.md +320 -0
  441. package/lib/libraries/weaviate/docs/ERROR_HANDLING.md +271 -0
  442. package/lib/libraries/weaviate/docs/MULTI_TENANCY.md +348 -0
  443. package/lib/libraries/weaviate/docs/PERFORMANCE.md +602 -0
  444. package/lib/libraries/weaviate/docs/PLUGIN_DEVELOPMENT.md +547 -0
  445. package/lib/libraries/weaviate/docs/QUICK_START.md +443 -0
  446. package/lib/libraries/weaviate/docs/README.md +269 -0
  447. package/lib/libraries/weaviate/docs/SCHEMA_GUIDE.md +630 -0
  448. package/lib/libraries/weaviate/docs/WEAVIATE_README.md +520 -0
  449. package/lib/libraries/weaviate/errors/WeaviateError.ts +92 -0
  450. package/lib/libraries/weaviate/errors/index.ts +1 -0
  451. package/lib/libraries/weaviate/index.ts +35 -0
  452. package/lib/libraries/weaviate/library.json +26 -0
  453. package/lib/libraries/weaviate/plugins/index.ts +2 -0
  454. package/lib/libraries/weaviate/schemas/SchemaRegistry.ts +284 -0
  455. package/lib/libraries/weaviate/schemas/index.ts +2 -0
  456. package/lib/libraries/weaviate/types/BM25SearchOptions.ts +9 -0
  457. package/lib/libraries/weaviate/types/ExtendedWeaviateClient.ts +7 -0
  458. package/lib/libraries/weaviate/types/HybridSearchOptions.ts +11 -0
  459. package/lib/libraries/weaviate/types/MultiTenancy.ts +81 -0
  460. package/lib/libraries/weaviate/types/Plugin.ts +17 -0
  461. package/lib/libraries/weaviate/types/SchemaConfig.ts +25 -0
  462. package/lib/libraries/weaviate/types/SearchMethod.ts +8 -0
  463. package/lib/libraries/weaviate/types/SearchOptions.ts +16 -0
  464. package/lib/libraries/weaviate/types/SearchRequest.ts +19 -0
  465. package/lib/libraries/weaviate/types/SearchResult.ts +16 -0
  466. package/lib/libraries/weaviate/types/SearchableField.ts +87 -0
  467. package/lib/libraries/weaviate/types/VectorIndexConfig.ts +19 -0
  468. package/lib/libraries/weaviate/types/VectorSearchOptions.ts +18 -0
  469. package/lib/libraries/weaviate/types/VectorizerConfig.ts +8 -0
  470. package/lib/libraries/weaviate/types/index.ts +29 -0
  471. package/lib/libraries/weaviate/utils/TenantContextManager.ts +94 -0
  472. package/lib/modules/accounts/index.ts +47 -0
  473. package/lib/modules/accounts/module.json +15 -0
  474. package/lib/modules/accounts/permissions.ts +33 -0
  475. package/lib/modules/accounts/routes.ts +200 -0
  476. package/lib/modules/accounts/schema.ts +219 -0
  477. package/lib/modules/accounts/services/AccountService.ts +44 -0
  478. package/lib/modules/accounts/validation/schemas.ts +70 -0
  479. package/lib/modules/oauth/adapters/GmailOAuthAdapter.ts +35 -0
  480. package/lib/modules/oauth/adapters/GoogleOAuthAdapter.ts +278 -0
  481. package/lib/modules/oauth/adapters/MicrosoftOAuthAdapter.ts +269 -0
  482. package/lib/modules/oauth/adapters/MockOAuthAdapter.ts +138 -0
  483. package/lib/modules/oauth/adapters/OAuthAdapter.ts +211 -0
  484. package/lib/modules/oauth/adapters/OAuthAdapterRegistry.ts +77 -0
  485. package/lib/modules/oauth/adapters/OutlookOAuthAdapter.ts +38 -0
  486. package/lib/modules/oauth/index.ts +79 -0
  487. package/lib/modules/oauth/module.json +23 -0
  488. package/lib/modules/oauth/permissions.ts +39 -0
  489. package/lib/modules/oauth/routes.ts +497 -0
  490. package/lib/modules/oauth/schema.ts +127 -0
  491. package/lib/modules/oauth/services/OAuthConnectionService.ts +147 -0
  492. package/lib/modules/oauth/state.ts +234 -0
  493. package/lib/modules/oauth/stateJtiCache.ts +85 -0
  494. package/lib/modules/oauth/verifyIdToken.ts +178 -0
  495. package/lib/modules/outbox/EventEmitter.ts +106 -0
  496. package/lib/modules/outbox/OutboxDrainer.ts +163 -0
  497. package/lib/modules/outbox/handlers/EventHandler.ts +115 -0
  498. package/lib/modules/outbox/index.ts +43 -0
  499. package/lib/modules/outbox/module.json +15 -0
  500. package/lib/modules/outbox/permissions.ts +36 -0
  501. package/lib/modules/outbox/routes.ts +219 -0
  502. package/lib/modules/outbox/schema.ts +207 -0
  503. package/lib/modules/outbox/services/OutboxEventService.ts +223 -0
  504. package/lib/observability/logger.d.ts +30 -0
  505. package/lib/observability/logger.d.ts.map +1 -0
  506. package/lib/observability/logger.js +110 -0
  507. package/lib/observability/logger.js.map +1 -0
  508. package/lib/observability/metrics.d.ts +3 -0
  509. package/lib/observability/metrics.d.ts.map +1 -0
  510. package/lib/observability/metrics.js +3 -0
  511. package/lib/observability/metrics.js.map +1 -0
  512. package/lib/observability/otel.d.ts +3 -0
  513. package/lib/observability/otel.d.ts.map +1 -0
  514. package/lib/observability/otel.js +3 -0
  515. package/lib/observability/otel.js.map +1 -0
  516. package/lib/observability/safeErrorFields.d.ts +14 -0
  517. package/lib/observability/safeErrorFields.d.ts.map +1 -0
  518. package/lib/observability/safeErrorFields.js +14 -0
  519. package/lib/observability/safeErrorFields.js.map +1 -0
  520. package/lib/observability/tracing.d.ts +3 -0
  521. package/lib/observability/tracing.d.ts.map +1 -0
  522. package/lib/observability/tracing.js +3 -0
  523. package/lib/observability/tracing.js.map +1 -0
  524. package/lib/package.json +4 -0
  525. package/lib/testing.d.ts +3 -0
  526. package/lib/testing.d.ts.map +1 -0
  527. package/lib/testing.js +3 -0
  528. package/lib/testing.js.map +1 -0
  529. package/package.json +193 -3
  530. package/templates/default/.claude/agents/qa-brief.md +106 -0
  531. package/templates/default/.claude/commands/sherpa-brief.md +23 -0
  532. package/templates/default/.cursor/rules/api.mdc +80 -0
  533. package/templates/default/.cursor/rules/commits.mdc +88 -0
  534. package/templates/default/.cursor/rules/security.mdc +92 -0
  535. package/templates/default/.cursor/rules/testing.mdc +123 -0
  536. package/templates/default/.cursor/rules/typescript.mdc +86 -0
  537. package/templates/default/.env.example +79 -0
  538. package/templates/default/.github/workflows/sherpa-brief.yml +180 -0
  539. package/templates/default/AGENTS.md +166 -0
  540. package/templates/default/CLAUDE.md +17 -0
  541. package/templates/default/README.md +97 -0
  542. package/templates/default/_gitignore +27 -0
  543. package/templates/default/docker-compose.yml +83 -0
  544. package/templates/default/drizzle.config.ts +34 -0
  545. package/templates/default/eslint.config.mjs +106 -0
  546. package/templates/default/package.json +57 -0
  547. package/templates/default/ship-api.config.ts +21 -0
  548. package/templates/default/src/client.ts +34 -0
  549. package/templates/default/src/config/modules.ts +23 -0
  550. package/templates/default/src/db/schema.ts +26 -0
  551. package/templates/default/src/environment.ts +81 -0
  552. package/templates/default/src/index.test.ts +53 -0
  553. package/templates/default/src/index.ts +11 -0
  554. package/templates/default/src/instrumentation.ts +13 -0
  555. package/templates/default/src/server.ts +90 -0
  556. package/templates/default/tsconfig.json +24 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "ai",
3
+ "description": "LLM helper library — provider adapters (Anthropic, OpenAI), prompt registry, structured outputs, tool-calling, RAG, and an experimental agent loop. Pluggable LLMProvider interface; concrete adapters are opt-in (install only the SDK you use).",
4
+ "version": "0.2.0",
5
+ "dependencies": [],
6
+ "npmDependencies": {},
7
+ "optionalNpmDependencies": {
8
+ "@anthropic-ai/sdk": "^0.91.0",
9
+ "openai": "^6.0.0"
10
+ },
11
+ "requiredEnvVars": [],
12
+ "optionalEnvVars": ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"],
13
+ "postInstall": [
14
+ "Install the SDK for the providers you need: `npm i @anthropic-ai/sdk` and/or `npm i openai`",
15
+ "Import { type LLMProvider } from '@sixthsummit/ship-api/libraries/ai' and the adapter you want (e.g. AnthropicAdapter)",
16
+ "Construct the adapter with your API key: `const llm = new AnthropicAdapter({ apiKey: env.ANTHROPIC_API_KEY })`",
17
+ "All adapters share the same `LLMProvider` interface — swap providers without changing call sites"
18
+ ]
19
+ }
@@ -0,0 +1,377 @@
1
+ import type { LLMProvider } from "../adapters/LLMProvider.js";
2
+ import type { ToolContext, ToolRegistry } from "../tools/defineTool.js";
3
+ import type {
4
+ CompleteResult,
5
+ Message,
6
+ MessageContentPart,
7
+ StopReason,
8
+ TokenUsage,
9
+ ToolChoice,
10
+ ToolResultPart,
11
+ ToolUsePart,
12
+ } from "../types.js";
13
+
14
+ /**
15
+ * `agentLoop({ llm, tools, messages, ... })` — runs the model →
16
+ * tool-call → execute → continue cycle until the model returns
17
+ * `end_turn` (or `max_tokens` / `content_filter`), or until
18
+ * `maxIterations` is exceeded.
19
+ *
20
+ * Each iteration:
21
+ * 1. Call `llm.complete` with the running history + tool definitions.
22
+ * 2. If the response has `tool_use` content parts, execute each via
23
+ * the registry and append a `user` message containing the
24
+ * `tool_result` parts. Loop.
25
+ * 3. Otherwise, return — the model is done.
26
+ *
27
+ * The `assistant` message we append to history preserves *every*
28
+ * content part the model emitted (text + tool_use), in order, so the
29
+ * provider sees a faithful turn record on the next request — Anthropic
30
+ * (and OpenAI) require the assistant message to round-trip exactly so
31
+ * the tool_use IDs align with the matching tool_result.
32
+ *
33
+ * Errors:
34
+ * - Tool handlers that throw → captured as `isError: true`
35
+ * `tool_result` so the model can recover. The loop survives.
36
+ * - Tool not found in the registry → also captured as
37
+ * `isError: true` with a clear message; the model adapts.
38
+ * - `maxIterations` exceeded → throws `AgentLoopMaxIterationsError`
39
+ * with the partial history attached for debugging.
40
+ * - `signal` aborts → SDK rejects, the throw propagates out of the
41
+ * loop without further iteration.
42
+ *
43
+ * Observability hook: `onEvent(event)` fires synchronously for each
44
+ * lifecycle event. Consumers wire it to `streamSSE`, OTel spans,
45
+ * prompt-eval logs — anything that wants per-step visibility. Awaited
46
+ * if it returns a promise so callers can backpressure (e.g. SSE
47
+ * write).
48
+ *
49
+ * @experimental — AI-R2. NOT on the stable API surface; carries no semver
50
+ * stability promise and is expected to be superseded by MCP / provider-native
51
+ * agent runtimes. Import from `@sixthsummit/ship-api/libraries/ai/experimental`.
52
+ * Durable code should prefer `completeStructured` (single-shot) or call
53
+ * `llm.complete` directly.
54
+ */
55
+
56
+ export interface AgentLoopOptions {
57
+ /** Provider that drives each iteration. */
58
+ llm: LLMProvider;
59
+ /** Tools the model can invoke. May be empty (degrades to plain `complete`). */
60
+ tools?: ToolRegistry;
61
+ /** Initial conversation history. The loop appends to a copy; the input is not mutated. */
62
+ messages: Message[];
63
+ /** Model identifier. Forwarded to `llm.complete` on every iteration. */
64
+ model: string;
65
+ /** Top-level system prompt. */
66
+ system?: string;
67
+ /**
68
+ * Per-iteration `max_tokens` cap forwarded to `llm.complete`. Adapter
69
+ * defaults apply when omitted.
70
+ */
71
+ maxTokens?: number;
72
+ /** Sampling temperature forwarded to `llm.complete`. */
73
+ temperature?: number;
74
+ /** Tool-choice override. Defaults to `{ type: "auto" }` when tools are present. */
75
+ toolChoice?: ToolChoice;
76
+ /**
77
+ * Provider-native passthrough forwarded to `llm.complete` on every
78
+ * iteration (e.g. prompt caching, extended thinking). Without it the
79
+ * seam's pass-through never reaches the adapter through the loop (AI-R1).
80
+ */
81
+ providerOptions?: Record<string, unknown>;
82
+ /** Request-tagging forwarded to `llm.complete` for observability / cost tracking. */
83
+ metadata?: Record<string, string>;
84
+ /**
85
+ * Maximum number of model→tool→model round-trips. The loop throws
86
+ * `AgentLoopMaxIterationsError` if the model never returns
87
+ * `end_turn` within this budget. Default 10.
88
+ */
89
+ maxIterations?: number;
90
+ /** Cancels in-flight provider requests + tool handlers. */
91
+ signal?: AbortSignal;
92
+ /**
93
+ * Forwarded to each tool handler's `ToolContext.metadata`. Typical
94
+ * contents: `{ requestId, userId, tenantId }`. Caller-defined.
95
+ */
96
+ toolMetadata?: Record<string, unknown>;
97
+ /** Lifecycle hook — see `AgentEvent` for event shapes. */
98
+ onEvent?: (event: AgentEvent) => void | Promise<void>;
99
+ }
100
+
101
+ export type AgentEvent =
102
+ | { type: "iteration_start"; iteration: number; messages: Message[] }
103
+ | { type: "model_response"; iteration: number; result: CompleteResult }
104
+ | {
105
+ type: "tool_call";
106
+ iteration: number;
107
+ toolUseId: string;
108
+ name: string;
109
+ input: Record<string, unknown>;
110
+ }
111
+ | {
112
+ type: "tool_result";
113
+ iteration: number;
114
+ toolUseId: string;
115
+ name: string;
116
+ ok: boolean;
117
+ output?: unknown;
118
+ error?: string;
119
+ }
120
+ | {
121
+ type: "iteration_end";
122
+ iteration: number;
123
+ stopReason: StopReason;
124
+ }
125
+ | {
126
+ type: "complete";
127
+ finalText: string;
128
+ iterations: number;
129
+ totalUsage: TokenUsage;
130
+ };
131
+
132
+ export interface AgentLoopResult {
133
+ /** The terminal `complete()` response — i.e. the one with `stopReason !== "tool_use"`. */
134
+ finalMessage: CompleteResult;
135
+ /** Convenience: the final assistant text (already on `finalMessage.text`). */
136
+ finalText: string;
137
+ /** Number of model calls made (≥ 1). */
138
+ iterations: number;
139
+ /** Sum of input + output tokens across every iteration. */
140
+ totalUsage: TokenUsage;
141
+ /**
142
+ * Full conversation history as the loop saw it after termination,
143
+ * including all tool_use + tool_result content parts. Useful for
144
+ * audit trails / tests.
145
+ */
146
+ history: Message[];
147
+ }
148
+
149
+ export class AgentLoopError extends Error {
150
+ constructor(message: string) {
151
+ super(message);
152
+ this.name = "AgentLoopError";
153
+ }
154
+ }
155
+
156
+ export class AgentLoopMaxIterationsError extends AgentLoopError {
157
+ constructor(
158
+ public readonly iterations: number,
159
+ public readonly history: Message[],
160
+ ) {
161
+ super(`Agent loop exceeded maxIterations=${iterations} without reaching end_turn`);
162
+ this.name = "AgentLoopMaxIterationsError";
163
+ }
164
+ }
165
+
166
+ const DEFAULT_MAX_ITERATIONS = 10;
167
+
168
+ export async function agentLoop(opts: AgentLoopOptions): Promise<AgentLoopResult> {
169
+ const maxIterations = opts.maxIterations ?? DEFAULT_MAX_ITERATIONS;
170
+ const tools = opts.tools;
171
+ const toolDefs = tools?.getDefinitions();
172
+ const toolChoice =
173
+ opts.toolChoice ?? (toolDefs && toolDefs.length > 0 ? { type: "auto" } : undefined);
174
+ const onEvent = opts.onEvent ?? (() => undefined);
175
+
176
+ const history: Message[] = [...opts.messages];
177
+ let totalUsage: TokenUsage = { inputTokens: 0, outputTokens: 0 };
178
+
179
+ for (let iteration = 1; iteration <= maxIterations; iteration++) {
180
+ if (opts.signal?.aborted) {
181
+ throw new AgentLoopError("Aborted before iteration " + iteration);
182
+ }
183
+ await onEvent({ type: "iteration_start", iteration, messages: history });
184
+
185
+ const result = await opts.llm.complete({
186
+ model: opts.model,
187
+ // Defensive copy: the loop mutates `history` post-call by
188
+ // appending the assistant turn + tool_results. Passing the live
189
+ // reference would leak that mutation back into adapter retry
190
+ // logic / test assertions on `mock.calls[].messages`.
191
+ messages: [...history],
192
+ system: opts.system,
193
+ maxTokens: opts.maxTokens,
194
+ temperature: opts.temperature,
195
+ tools: toolDefs && toolDefs.length > 0 ? toolDefs : undefined,
196
+ toolChoice,
197
+ signal: opts.signal,
198
+ providerOptions: opts.providerOptions,
199
+ metadata: opts.metadata,
200
+ });
201
+ totalUsage = accumulateUsage(totalUsage, result.usage);
202
+ await onEvent({ type: "model_response", iteration, result });
203
+
204
+ if (result.stopReason !== "tool_use") {
205
+ await onEvent({
206
+ type: "iteration_end",
207
+ iteration,
208
+ stopReason: result.stopReason,
209
+ });
210
+ // Persist the final assistant turn so the returned history is
211
+ // self-consistent (consumer can replay).
212
+ history.push({ role: "assistant", content: result.content });
213
+ await onEvent({
214
+ type: "complete",
215
+ finalText: result.text,
216
+ iterations: iteration,
217
+ totalUsage,
218
+ });
219
+ return {
220
+ finalMessage: result,
221
+ finalText: result.text,
222
+ iterations: iteration,
223
+ totalUsage,
224
+ history,
225
+ };
226
+ }
227
+
228
+ // Round-trip the assistant turn verbatim so tool_use IDs align with
229
+ // the tool_result IDs the next user message carries.
230
+ history.push({ role: "assistant", content: result.content });
231
+
232
+ const toolUseParts = result.content.filter((p): p is ToolUsePart => p.type === "tool_use");
233
+ if (toolUseParts.length === 0) {
234
+ // Provider claimed `tool_use` but emitted no tool_use blocks —
235
+ // treat as terminal to avoid infinite loop.
236
+ await onEvent({
237
+ type: "iteration_end",
238
+ iteration,
239
+ stopReason: "unknown",
240
+ });
241
+ await onEvent({
242
+ type: "complete",
243
+ finalText: result.text,
244
+ iterations: iteration,
245
+ totalUsage,
246
+ });
247
+ return {
248
+ finalMessage: result,
249
+ finalText: result.text,
250
+ iterations: iteration,
251
+ totalUsage,
252
+ history,
253
+ };
254
+ }
255
+
256
+ const toolResults: ToolResultPart[] = [];
257
+ for (const tu of toolUseParts) {
258
+ await onEvent({
259
+ type: "tool_call",
260
+ iteration,
261
+ toolUseId: tu.id,
262
+ name: tu.name,
263
+ input: tu.input,
264
+ });
265
+ const tool = tools?.lookup(tu.name);
266
+ if (!tool) {
267
+ const error = `tool "${tu.name}" not registered`;
268
+ toolResults.push({
269
+ type: "tool_result",
270
+ toolUseId: tu.id,
271
+ content: error,
272
+ isError: true,
273
+ });
274
+ await onEvent({
275
+ type: "tool_result",
276
+ iteration,
277
+ toolUseId: tu.id,
278
+ name: tu.name,
279
+ ok: false,
280
+ error,
281
+ });
282
+ continue;
283
+ }
284
+ const ctx: ToolContext = {
285
+ signal: opts.signal,
286
+ metadata: opts.toolMetadata,
287
+ };
288
+ const exec = await tool.execute(tu.input, ctx);
289
+ if (exec.ok) {
290
+ toolResults.push({
291
+ type: "tool_result",
292
+ toolUseId: tu.id,
293
+ content: serializeToolOutput(exec.output),
294
+ });
295
+ await onEvent({
296
+ type: "tool_result",
297
+ iteration,
298
+ toolUseId: tu.id,
299
+ name: tu.name,
300
+ ok: true,
301
+ output: exec.output,
302
+ });
303
+ } else {
304
+ toolResults.push({
305
+ type: "tool_result",
306
+ toolUseId: tu.id,
307
+ content: exec.content,
308
+ isError: true,
309
+ });
310
+ await onEvent({
311
+ type: "tool_result",
312
+ iteration,
313
+ toolUseId: tu.id,
314
+ name: tu.name,
315
+ ok: false,
316
+ error: exec.content,
317
+ });
318
+ }
319
+ }
320
+
321
+ history.push({ role: "user", content: toolResults });
322
+ await onEvent({
323
+ type: "iteration_end",
324
+ iteration,
325
+ stopReason: "tool_use",
326
+ });
327
+ }
328
+
329
+ throw new AgentLoopMaxIterationsError(maxIterations, history);
330
+ }
331
+
332
+ function accumulateUsage(a: TokenUsage, b: TokenUsage): TokenUsage {
333
+ return {
334
+ inputTokens: a.inputTokens + b.inputTokens,
335
+ outputTokens: a.outputTokens + b.outputTokens,
336
+ cacheReadInputTokens: sumOpt(a.cacheReadInputTokens, b.cacheReadInputTokens) ?? undefined,
337
+ cacheCreationInputTokens:
338
+ sumOpt(a.cacheCreationInputTokens, b.cacheCreationInputTokens) ?? undefined,
339
+ };
340
+ }
341
+
342
+ function sumOpt(a?: number, b?: number): number | undefined {
343
+ if (a === undefined && b === undefined) return undefined;
344
+ return (a ?? 0) + (b ?? 0);
345
+ }
346
+
347
+ function serializeToolOutput(output: unknown): string {
348
+ if (typeof output === "string") return output;
349
+ if (output === undefined || output === null) return "";
350
+ try {
351
+ return JSON.stringify(output);
352
+ } catch {
353
+ return String(output);
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Helper for assertions / observability — flatten the assistant text
359
+ * across every iteration in the history. Useful when you want the
360
+ * model's full reasoning trace, not just the terminal response.
361
+ */
362
+ export function collectAssistantText(history: Message[]): string[] {
363
+ const out: string[] = [];
364
+ for (const msg of history) {
365
+ if (msg.role !== "assistant") continue;
366
+ if (typeof msg.content === "string") {
367
+ out.push(msg.content);
368
+ } else {
369
+ const text = (msg.content as MessageContentPart[])
370
+ .filter((p): p is { type: "text"; text: string } => p.type === "text")
371
+ .map((p) => p.text)
372
+ .join("");
373
+ if (text) out.push(text);
374
+ }
375
+ }
376
+ return out;
377
+ }
@@ -0,0 +1,177 @@
1
+ import type { LLMProvider } from "../adapters/LLMProvider.js";
2
+ import { definePrompt, type Prompt } from "../prompts/definePrompt.js";
3
+ import type { CompleteResult, Message } from "../types.js";
4
+
5
+ /**
6
+ * `retrieveAndAnswer({ llm, vectorStore, query, ... })` — RAG pipeline
7
+ * primitive per plan §G. Retrieves the top-k relevant documents from a
8
+ * `VectorStore`, formats them into a context block, and asks the
9
+ * `LLMProvider` to answer the query grounded in those documents.
10
+ *
11
+ * Pluggable on both axes:
12
+ * - `LLMProvider` is the cross-provider interface from
13
+ * `adapters/LLMProvider.ts` — Anthropic / OpenAI / future
14
+ * adapters all work identically.
15
+ * - `VectorStore` is a structural interface defined here. The
16
+ * library deliberately takes no dep on `libraries/weaviate` or
17
+ * any specific store — consumers pass their own implementation
18
+ * (Weaviate, Pinecone, in-memory, Postgres pgvector, …). Keeping
19
+ * the dep narrow means the RAG helper is usable with any
20
+ * retrieval backend the consumer happens to have.
21
+ *
22
+ * The prompt is overridable: callers can pass their own
23
+ * `Prompt<{ query, documents }>` to swap the template (e.g., domain-
24
+ * specific framing, multi-language). The default produces the
25
+ * standard "answer the question using only the documents below"
26
+ * template most RAG flows want.
27
+ *
28
+ * Output shape: `{ answer, sources, raw }`. `sources` is the original
29
+ * `RetrievedDocument[]` (id + score + metadata), so callers can
30
+ * surface citations in their UI without re-querying.
31
+ */
32
+
33
+ export interface RetrievedDocument {
34
+ /** Stable identifier — surfaced as a citation marker in the prompt. */
35
+ id: string;
36
+ /** The text the model sees. */
37
+ text: string;
38
+ /** Similarity / relevance score from the store. Higher is better. */
39
+ score: number;
40
+ /** Free-form metadata (source URL, author, timestamp, …). */
41
+ metadata?: Record<string, unknown>;
42
+ }
43
+
44
+ export interface VectorStoreSearchOptions {
45
+ query: string;
46
+ /** Caller-defined ceiling on retrieved document count. */
47
+ topK: number;
48
+ /**
49
+ * Optional store-specific filter (e.g. tenant scoping). Pass
50
+ * unchanged to the underlying store.
51
+ */
52
+ filter?: Record<string, unknown>;
53
+ signal?: AbortSignal;
54
+ }
55
+
56
+ export interface VectorStore {
57
+ /** Stable identifier ("weaviate", "pinecone", "pgvector", …). */
58
+ readonly name: string;
59
+ /** Retrieve the top-k most relevant documents for the given query. */
60
+ search(opts: VectorStoreSearchOptions): Promise<RetrievedDocument[]>;
61
+ }
62
+
63
+ export interface RetrieveAndAnswerOptions {
64
+ /** Provider that produces the final answer. */
65
+ llm: LLMProvider;
66
+ /** Vector store to query. */
67
+ vectorStore: VectorStore;
68
+ /** The user question. */
69
+ query: string;
70
+ /** Top-k documents to retrieve. Default 5. */
71
+ topK?: number;
72
+ /** Model id forwarded to `llm.complete`. */
73
+ model: string;
74
+ /**
75
+ * Top-level system prompt. Defaults to a faithful-attribution
76
+ * instruction; override to add tone / domain framing.
77
+ */
78
+ systemPrompt?: string;
79
+ /**
80
+ * Override the prompt template. Receives `{ query, documents }`
81
+ * (`documents` is the formatted context block). Defaults to the
82
+ * built-in `RAG_DEFAULT_PROMPT`.
83
+ */
84
+ promptTemplate?: Prompt<{ query: string; documents: string }>;
85
+ /**
86
+ * Filter forwarded to `vectorStore.search` — store-specific
87
+ * (tenant scoping, time range, …).
88
+ */
89
+ filter?: Record<string, unknown>;
90
+ /**
91
+ * Per-document context formatter. Defaults to numbered citation
92
+ * markers (`[1]`, `[2]`, …) that the model can cite back. Pass a
93
+ * custom formatter for richer formatting (markdown headers,
94
+ * metadata interpolation, …).
95
+ */
96
+ formatDocument?: (doc: RetrievedDocument, index: number) => string;
97
+ maxTokens?: number;
98
+ temperature?: number;
99
+ signal?: AbortSignal;
100
+ /**
101
+ * Provider-native passthrough forwarded to `llm.complete` (e.g. prompt
102
+ * caching for the system prompt / documents). Without it the seam's
103
+ * pass-through never reaches the adapter through RAG (AI-R1).
104
+ */
105
+ providerOptions?: Record<string, unknown>;
106
+ /** Request-tagging forwarded to `llm.complete` for observability / cost tracking. */
107
+ metadata?: Record<string, string>;
108
+ }
109
+
110
+ export interface RetrieveAndAnswerResult {
111
+ /** The model's answer text (joined `text` content parts). */
112
+ answer: string;
113
+ /** Documents the answer was grounded in, in retrieval order. */
114
+ sources: RetrievedDocument[];
115
+ /** The raw provider response (id / model / usage / etc.). */
116
+ raw: CompleteResult;
117
+ }
118
+
119
+ const DEFAULT_TOP_K = 5;
120
+ const DEFAULT_SYSTEM_PROMPT =
121
+ "You are a careful assistant. Answer the user's question using only the documents provided. If the documents don't contain the answer, say so explicitly. Cite document numbers (e.g. [1], [2]) for any claim sourced from a document.";
122
+
123
+ export const RAG_DEFAULT_PROMPT = definePrompt({
124
+ id: "ship-api.rag.retrieve_and_answer",
125
+ version: 1,
126
+ template:
127
+ "Question:\n{{query}}\n\nDocuments:\n{{documents}}\n\nAnswer the question using only the documents above. Cite document numbers in square brackets for each claim sourced from a document.",
128
+ description: "Default RAG prompt — grounded answer with citations.",
129
+ });
130
+
131
+ export async function retrieveAndAnswer(
132
+ opts: RetrieveAndAnswerOptions,
133
+ ): Promise<RetrieveAndAnswerResult> {
134
+ const topK = opts.topK ?? DEFAULT_TOP_K;
135
+ const formatDocument = opts.formatDocument ?? defaultDocumentFormatter;
136
+ const promptTemplate = opts.promptTemplate ?? RAG_DEFAULT_PROMPT;
137
+
138
+ const sources = await opts.vectorStore.search({
139
+ query: opts.query,
140
+ topK,
141
+ filter: opts.filter,
142
+ signal: opts.signal,
143
+ });
144
+
145
+ const documentsBlock = sources.map((doc, i) => formatDocument(doc, i)).join("\n\n");
146
+
147
+ const userPrompt = promptTemplate.render({
148
+ query: opts.query,
149
+ documents:
150
+ sources.length === 0
151
+ ? "(no documents retrieved — answer should explicitly say no source material was available)"
152
+ : documentsBlock,
153
+ });
154
+
155
+ const messages: Message[] = [{ role: "user", content: userPrompt }];
156
+
157
+ const raw = await opts.llm.complete({
158
+ model: opts.model,
159
+ messages,
160
+ system: opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT,
161
+ maxTokens: opts.maxTokens,
162
+ temperature: opts.temperature,
163
+ signal: opts.signal,
164
+ providerOptions: opts.providerOptions,
165
+ metadata: opts.metadata,
166
+ });
167
+
168
+ return {
169
+ answer: raw.text,
170
+ sources,
171
+ raw,
172
+ };
173
+ }
174
+
175
+ function defaultDocumentFormatter(doc: RetrievedDocument, index: number): string {
176
+ return `[${index + 1}] (${doc.id}) ${doc.text}`;
177
+ }
@@ -0,0 +1,94 @@
1
+ import type { StreamEvent } from "../types.js";
2
+
3
+ /**
4
+ * Structural view of the kernel stream seam handed to streaming operation
5
+ * handlers (`OperationStream` from `@sixthsummit/ship-core`). Declared here so
6
+ * the library keeps zero runtime or type dependencies on the kernel package.
7
+ */
8
+ export interface LLMFrameStream<TFrame> {
9
+ readonly emit: (frame: TFrame) => Promise<void>;
10
+ readonly signal: AbortSignal;
11
+ }
12
+
13
+ /**
14
+ * Minimum shape `streamLLM` requires: a string `type` plus JSON-serializable
15
+ * fields. The full `StreamEvent` union from this library fits.
16
+ */
17
+ export interface LLMStreamFrame {
18
+ readonly type: string;
19
+ readonly [key: string]: unknown;
20
+ }
21
+
22
+ export interface StreamLLMOptions<TFrame extends LLMStreamFrame> {
23
+ /**
24
+ * Called once if the provider iterator throws, before the error propagates
25
+ * to the kernel (which delivers it as a terminal `error` frame). Throwing
26
+ * here is swallowed so the propagation still completes.
27
+ */
28
+ readonly onError?: (error: Error) => Promise<void> | void;
29
+ /**
30
+ * Maps a provider event onto the operation's declared frame. Defaults to
31
+ * passing the event through unchanged.
32
+ */
33
+ readonly toFrame?: (event: StreamEvent | LLMStreamFrame, index: number) => TFrame;
34
+ }
35
+
36
+ export interface StreamLLMResult {
37
+ /** Number of frames handed to `emit`. */
38
+ readonly frames: number;
39
+ /** True when the run stopped early because the operation signal aborted. */
40
+ readonly aborted: boolean;
41
+ }
42
+
43
+ /**
44
+ * `streamLLM(stream, events, options?)` — pipes an LLM provider stream
45
+ * (typically `LLMProvider.streamComplete()`) through the kernel stream seam.
46
+ * Each provider event becomes one validated frame; cancellation flows from the
47
+ * operation's `AbortSignal` back into the provider iterator via `return()`.
48
+ *
49
+ * This is the operation-kernel counterpart of the compatibility
50
+ * `streamLLM(c, events)` Hono helper in `@sixthsummit/ship-api`, whose SSE
51
+ * layout (`event: <type>`) is unchanged. Under the kernel the frame is the
52
+ * whole event object and the SSE event name is always `frame`.
53
+ *
54
+ * Usage:
55
+ * ```ts
56
+ * handler: async ({ input, services, stream }) => {
57
+ * const events = services.llm.streamComplete({ model, messages, signal: stream.signal });
58
+ * const { frames } = await streamLLM(stream, events);
59
+ * return { frames };
60
+ * }
61
+ * ```
62
+ */
63
+ export async function streamLLM<TFrame extends LLMStreamFrame = StreamEvent>(
64
+ stream: LLMFrameStream<TFrame>,
65
+ events: AsyncIterable<StreamEvent | LLMStreamFrame>,
66
+ options: StreamLLMOptions<TFrame> = {},
67
+ ): Promise<StreamLLMResult> {
68
+ const toFrame = options.toFrame ?? ((event) => event as TFrame);
69
+ const iterator = events[Symbol.asyncIterator]();
70
+ let frames = 0;
71
+ try {
72
+ while (true) {
73
+ if (stream.signal.aborted) {
74
+ await iterator.return?.();
75
+ return { frames, aborted: true };
76
+ }
77
+ const next = await iterator.next();
78
+ if (next.done) return { frames, aborted: false };
79
+ await stream.emit(toFrame(next.value, frames));
80
+ frames += 1;
81
+ }
82
+ } catch (caught) {
83
+ const error = caught instanceof Error ? caught : new Error(String(caught));
84
+ if (options.onError) {
85
+ try {
86
+ await options.onError(error);
87
+ } catch {
88
+ // The hook must not mask the original failure.
89
+ }
90
+ }
91
+ await iterator.return?.().catch(() => undefined);
92
+ throw error;
93
+ }
94
+ }