@homeflare/alchemy 0.42.0 → 0.44.0

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 (648) hide show
  1. package/README.md +10 -1
  2. package/dist/caddy/index.js +35 -1
  3. package/dist/caddy/index.js.map +3 -3
  4. package/dist/launchd/index.js +35 -1
  5. package/dist/launchd/index.js.map +3 -3
  6. package/dist/linux/index.js +35 -1
  7. package/dist/linux/index.js.map +3 -3
  8. package/dist/litellm/access-group-form.d.ts +26 -0
  9. package/dist/litellm/access-group-form.d.ts.map +1 -0
  10. package/dist/litellm/access-group-operations.d.ts +37 -0
  11. package/dist/litellm/access-group-operations.d.ts.map +1 -0
  12. package/dist/litellm/access-group-types.d.ts +49 -0
  13. package/dist/litellm/access-group-types.d.ts.map +1 -0
  14. package/dist/litellm/access-group.d.ts +55 -0
  15. package/dist/litellm/access-group.d.ts.map +1 -0
  16. package/dist/litellm/budget-errors.d.ts +36 -0
  17. package/dist/litellm/budget-errors.d.ts.map +1 -0
  18. package/dist/litellm/budget-form.d.ts +50 -0
  19. package/dist/litellm/budget-form.d.ts.map +1 -0
  20. package/dist/litellm/budget-operations.d.ts +20 -0
  21. package/dist/litellm/budget-operations.d.ts.map +1 -0
  22. package/dist/litellm/budget.d.ts +61 -0
  23. package/dist/litellm/budget.d.ts.map +1 -0
  24. package/dist/litellm/credential-errors.d.ts +131 -0
  25. package/dist/litellm/credential-errors.d.ts.map +1 -0
  26. package/dist/litellm/credential-form.d.ts +79 -0
  27. package/dist/litellm/credential-form.d.ts.map +1 -0
  28. package/dist/litellm/credential-operations.d.ts +84 -0
  29. package/dist/litellm/credential-operations.d.ts.map +1 -0
  30. package/dist/litellm/credential-rewrite.d.ts +6 -0
  31. package/dist/litellm/credential-rewrite.d.ts.map +1 -0
  32. package/dist/litellm/credential-types.d.ts +87 -0
  33. package/dist/litellm/credential-types.d.ts.map +1 -0
  34. package/dist/litellm/credential-values.d.ts +53 -0
  35. package/dist/litellm/credential-values.d.ts.map +1 -0
  36. package/dist/litellm/credential.d.ts +83 -0
  37. package/dist/litellm/credential.d.ts.map +1 -0
  38. package/dist/litellm/fake-access-group-litellm.d.ts +34 -0
  39. package/dist/litellm/fake-access-group-litellm.d.ts.map +1 -0
  40. package/dist/litellm/fake-credential-litellm.d.ts +54 -0
  41. package/dist/litellm/fake-credential-litellm.d.ts.map +1 -0
  42. package/dist/litellm/fake-keys.d.ts +53 -0
  43. package/dist/litellm/fake-keys.d.ts.map +1 -0
  44. package/dist/litellm/fake-litellm.d.ts +9 -1
  45. package/dist/litellm/fake-litellm.d.ts.map +1 -1
  46. package/dist/litellm/fake-mcp-litellm.d.ts +67 -0
  47. package/dist/litellm/fake-mcp-litellm.d.ts.map +1 -0
  48. package/dist/litellm/fake-model-litellm-post-update.d.ts +49 -0
  49. package/dist/litellm/fake-model-litellm-post-update.d.ts.map +1 -0
  50. package/dist/litellm/fake-model-litellm.d.ts +48 -0
  51. package/dist/litellm/fake-model-litellm.d.ts.map +1 -0
  52. package/dist/litellm/fake-policy-attachment-litellm.d.ts +33 -0
  53. package/dist/litellm/fake-policy-attachment-litellm.d.ts.map +1 -0
  54. package/dist/litellm/fake-policy-litellm.d.ts +32 -0
  55. package/dist/litellm/fake-policy-litellm.d.ts.map +1 -0
  56. package/dist/litellm/fake-registry-base.d.ts +42 -0
  57. package/dist/litellm/fake-registry-base.d.ts.map +1 -0
  58. package/dist/litellm/fake-stack.d.ts +8 -1
  59. package/dist/litellm/fake-stack.d.ts.map +1 -1
  60. package/dist/litellm/fake-team-litellm.d.ts +47 -0
  61. package/dist/litellm/fake-team-litellm.d.ts.map +1 -0
  62. package/dist/litellm/fake-tool-litellm.d.ts +28 -0
  63. package/dist/litellm/fake-tool-litellm.d.ts.map +1 -0
  64. package/dist/litellm/fake-toolset-litellm.d.ts +29 -0
  65. package/dist/litellm/fake-toolset-litellm.d.ts.map +1 -0
  66. package/dist/litellm/index.d.ts +20 -0
  67. package/dist/litellm/index.d.ts.map +1 -1
  68. package/dist/litellm/index.js +3201 -2
  69. package/dist/litellm/index.js.map +70 -5
  70. package/dist/litellm/key-errors.d.ts +169 -0
  71. package/dist/litellm/key-errors.d.ts.map +1 -0
  72. package/dist/litellm/key-form.d.ts +119 -0
  73. package/dist/litellm/key-form.d.ts.map +1 -0
  74. package/dist/litellm/key-harness.d.ts +41 -0
  75. package/dist/litellm/key-harness.d.ts.map +1 -0
  76. package/dist/litellm/key-metadata-errors.d.ts +30 -0
  77. package/dist/litellm/key-metadata-errors.d.ts.map +1 -0
  78. package/dist/litellm/key-metadata.d.ts +22 -0
  79. package/dist/litellm/key-metadata.d.ts.map +1 -0
  80. package/dist/litellm/key-operations.d.ts +63 -0
  81. package/dist/litellm/key-operations.d.ts.map +1 -0
  82. package/dist/litellm/key-secret.d.ts +33 -0
  83. package/dist/litellm/key-secret.d.ts.map +1 -0
  84. package/dist/litellm/key.d.ts +78 -0
  85. package/dist/litellm/key.d.ts.map +1 -0
  86. package/dist/litellm/mcp-server-credential.d.ts +50 -0
  87. package/dist/litellm/mcp-server-credential.d.ts.map +1 -0
  88. package/dist/litellm/mcp-server-errors.d.ts +101 -0
  89. package/dist/litellm/mcp-server-errors.d.ts.map +1 -0
  90. package/dist/litellm/mcp-server-form.d.ts +56 -0
  91. package/dist/litellm/mcp-server-form.d.ts.map +1 -0
  92. package/dist/litellm/mcp-server-locate.d.ts +26 -0
  93. package/dist/litellm/mcp-server-locate.d.ts.map +1 -0
  94. package/dist/litellm/mcp-server-operations.d.ts +63 -0
  95. package/dist/litellm/mcp-server-operations.d.ts.map +1 -0
  96. package/dist/litellm/mcp-server-shadow.d.ts +24 -0
  97. package/dist/litellm/mcp-server-shadow.d.ts.map +1 -0
  98. package/dist/litellm/mcp-server-types.d.ts +118 -0
  99. package/dist/litellm/mcp-server-types.d.ts.map +1 -0
  100. package/dist/litellm/mcp-server-url.d.ts +11 -0
  101. package/dist/litellm/mcp-server-url.d.ts.map +1 -0
  102. package/dist/litellm/mcp-server.d.ts +95 -0
  103. package/dist/litellm/mcp-server.d.ts.map +1 -0
  104. package/dist/litellm/model-claim.d.ts +24 -0
  105. package/dist/litellm/model-claim.d.ts.map +1 -0
  106. package/dist/litellm/model-credential.d.ts +12 -0
  107. package/dist/litellm/model-credential.d.ts.map +1 -0
  108. package/dist/litellm/model-errors.d.ts +119 -0
  109. package/dist/litellm/model-errors.d.ts.map +1 -0
  110. package/dist/litellm/model-form.d.ts +78 -0
  111. package/dist/litellm/model-form.d.ts.map +1 -0
  112. package/dist/litellm/model-locate.d.ts +13 -0
  113. package/dist/litellm/model-locate.d.ts.map +1 -0
  114. package/dist/litellm/model-operations.d.ts +59 -0
  115. package/dist/litellm/model-operations.d.ts.map +1 -0
  116. package/dist/litellm/model-types.d.ts +91 -0
  117. package/dist/litellm/model-types.d.ts.map +1 -0
  118. package/dist/litellm/model.d.ts +88 -0
  119. package/dist/litellm/model.d.ts.map +1 -0
  120. package/dist/litellm/operations.d.ts +22 -0
  121. package/dist/litellm/operations.d.ts.map +1 -1
  122. package/dist/litellm/policy-attachment-form.d.ts +19 -0
  123. package/dist/litellm/policy-attachment-form.d.ts.map +1 -0
  124. package/dist/litellm/policy-attachment-operations.d.ts +31 -0
  125. package/dist/litellm/policy-attachment-operations.d.ts.map +1 -0
  126. package/dist/litellm/policy-attachment-types.d.ts +48 -0
  127. package/dist/litellm/policy-attachment-types.d.ts.map +1 -0
  128. package/dist/litellm/policy-attachment.d.ts +61 -0
  129. package/dist/litellm/policy-attachment.d.ts.map +1 -0
  130. package/dist/litellm/policy-form.d.ts +22 -0
  131. package/dist/litellm/policy-form.d.ts.map +1 -0
  132. package/dist/litellm/policy-operations.d.ts +42 -0
  133. package/dist/litellm/policy-operations.d.ts.map +1 -0
  134. package/dist/litellm/policy-types.d.ts +57 -0
  135. package/dist/litellm/policy-types.d.ts.map +1 -0
  136. package/dist/litellm/policy.d.ts +65 -0
  137. package/dist/litellm/policy.d.ts.map +1 -0
  138. package/dist/litellm/providers.d.ts +1 -1
  139. package/dist/litellm/providers.d.ts.map +1 -1
  140. package/dist/litellm/registry-errors.d.ts +62 -0
  141. package/dist/litellm/registry-errors.d.ts.map +1 -0
  142. package/dist/litellm/registry-support.d.ts +42 -0
  143. package/dist/litellm/registry-support.d.ts.map +1 -0
  144. package/dist/litellm/team-form.d.ts +26 -0
  145. package/dist/litellm/team-form.d.ts.map +1 -0
  146. package/dist/litellm/team-members.d.ts +10 -0
  147. package/dist/litellm/team-members.d.ts.map +1 -0
  148. package/dist/litellm/team-operations.d.ts +38 -0
  149. package/dist/litellm/team-operations.d.ts.map +1 -0
  150. package/dist/litellm/team-permission.d.ts +35 -0
  151. package/dist/litellm/team-permission.d.ts.map +1 -0
  152. package/dist/litellm/team-types.d.ts +101 -0
  153. package/dist/litellm/team-types.d.ts.map +1 -0
  154. package/dist/litellm/team.d.ts +67 -0
  155. package/dist/litellm/team.d.ts.map +1 -0
  156. package/dist/litellm/tool-policy-form.d.ts +21 -0
  157. package/dist/litellm/tool-policy-form.d.ts.map +1 -0
  158. package/dist/litellm/tool-policy-operations.d.ts +30 -0
  159. package/dist/litellm/tool-policy-operations.d.ts.map +1 -0
  160. package/dist/litellm/tool-policy-types.d.ts +46 -0
  161. package/dist/litellm/tool-policy-types.d.ts.map +1 -0
  162. package/dist/litellm/tool-policy.d.ts +62 -0
  163. package/dist/litellm/tool-policy.d.ts.map +1 -0
  164. package/dist/litellm/toolset-form.d.ts +20 -0
  165. package/dist/litellm/toolset-form.d.ts.map +1 -0
  166. package/dist/litellm/toolset-operations.d.ts +39 -0
  167. package/dist/litellm/toolset-operations.d.ts.map +1 -0
  168. package/dist/litellm/toolset-types.d.ts +46 -0
  169. package/dist/litellm/toolset-types.d.ts.map +1 -0
  170. package/dist/litellm/toolset.d.ts +55 -0
  171. package/dist/litellm/toolset.d.ts.map +1 -0
  172. package/dist/openbao/auth-role-form.d.ts +9 -0
  173. package/dist/openbao/auth-role-form.d.ts.map +1 -1
  174. package/dist/openbao/auth-role-wire.d.ts.map +1 -1
  175. package/dist/openbao/fake-engines-roles.d.ts.map +1 -1
  176. package/dist/openbao/index.js +43 -6
  177. package/dist/openbao/index.js.map +5 -5
  178. package/dist/ownership/rows.d.ts +11 -0
  179. package/dist/ownership/rows.d.ts.map +1 -1
  180. package/dist/postgres/connection.d.ts +32 -2
  181. package/dist/postgres/connection.d.ts.map +1 -1
  182. package/dist/postgres/database-sql.d.ts +28 -9
  183. package/dist/postgres/database-sql.d.ts.map +1 -1
  184. package/dist/postgres/database.d.ts +1 -1
  185. package/dist/postgres/database.d.ts.map +1 -1
  186. package/dist/postgres/fake-grants-parse.d.ts +37 -0
  187. package/dist/postgres/fake-grants-parse.d.ts.map +1 -0
  188. package/dist/postgres/fake-grants-read.d.ts +61 -0
  189. package/dist/postgres/fake-grants-read.d.ts.map +1 -0
  190. package/dist/postgres/fake-grants-sql.d.ts +46 -0
  191. package/dist/postgres/fake-grants-sql.d.ts.map +1 -0
  192. package/dist/postgres/fake-grants-write.d.ts +29 -0
  193. package/dist/postgres/fake-grants-write.d.ts.map +1 -0
  194. package/dist/postgres/fake-role-sql.d.ts +40 -0
  195. package/dist/postgres/fake-role-sql.d.ts.map +1 -0
  196. package/dist/postgres/fake-schema-sql.d.ts +42 -0
  197. package/dist/postgres/fake-schema-sql.d.ts.map +1 -0
  198. package/dist/postgres/fake-sql-parse.d.ts +23 -0
  199. package/dist/postgres/fake-sql-parse.d.ts.map +1 -0
  200. package/dist/postgres/fake-sql-quote.d.ts +12 -0
  201. package/dist/postgres/fake-sql-quote.d.ts.map +1 -0
  202. package/dist/postgres/fake-sql.d.ts +42 -0
  203. package/dist/postgres/fake-sql.d.ts.map +1 -1
  204. package/dist/postgres/grants-attrs.d.ts +115 -0
  205. package/dist/postgres/grants-attrs.d.ts.map +1 -0
  206. package/dist/postgres/grants-declare.d.ts +88 -0
  207. package/dist/postgres/grants-declare.d.ts.map +1 -0
  208. package/dist/postgres/grants-diff.d.ts +25 -0
  209. package/dist/postgres/grants-diff.d.ts.map +1 -0
  210. package/dist/postgres/grants-errors.d.ts +137 -0
  211. package/dist/postgres/grants-errors.d.ts.map +1 -0
  212. package/dist/postgres/grants-existence.d.ts +14 -0
  213. package/dist/postgres/grants-existence.d.ts.map +1 -0
  214. package/dist/postgres/grants-ops.d.ts +65 -0
  215. package/dist/postgres/grants-ops.d.ts.map +1 -0
  216. package/dist/postgres/grants-ownership.d.ts +18 -0
  217. package/dist/postgres/grants-ownership.d.ts.map +1 -0
  218. package/dist/postgres/grants-plan-restore.d.ts +22 -0
  219. package/dist/postgres/grants-plan-restore.d.ts.map +1 -0
  220. package/dist/postgres/grants-plan.d.ts +65 -0
  221. package/dist/postgres/grants-plan.d.ts.map +1 -0
  222. package/dist/postgres/grants-read-defaults.d.ts +17 -0
  223. package/dist/postgres/grants-read-defaults.d.ts.map +1 -0
  224. package/dist/postgres/grants-read.d.ts +77 -0
  225. package/dist/postgres/grants-read.d.ts.map +1 -0
  226. package/dist/postgres/grants-refuse.d.ts +25 -0
  227. package/dist/postgres/grants-refuse.d.ts.map +1 -0
  228. package/dist/postgres/grants-sql.d.ts +42 -0
  229. package/dist/postgres/grants-sql.d.ts.map +1 -0
  230. package/dist/postgres/grants-words.d.ts +29 -0
  231. package/dist/postgres/grants-words.d.ts.map +1 -0
  232. package/dist/postgres/grants.d.ts +37 -0
  233. package/dist/postgres/grants.d.ts.map +1 -0
  234. package/dist/postgres/index.d.ts +35 -8
  235. package/dist/postgres/index.d.ts.map +1 -1
  236. package/dist/postgres/index.js +2063 -39
  237. package/dist/postgres/index.js.map +47 -7
  238. package/dist/postgres/installed-classifier.d.ts +13 -0
  239. package/dist/postgres/installed-classifier.d.ts.map +1 -0
  240. package/dist/postgres/providers.d.ts +17 -7
  241. package/dist/postgres/providers.d.ts.map +1 -1
  242. package/dist/postgres/psql-executor.d.ts +25 -0
  243. package/dist/postgres/psql-executor.d.ts.map +1 -0
  244. package/dist/postgres/role-attrs.d.ts +109 -0
  245. package/dist/postgres/role-attrs.d.ts.map +1 -0
  246. package/dist/postgres/role-diff.d.ts +22 -0
  247. package/dist/postgres/role-diff.d.ts.map +1 -0
  248. package/dist/postgres/role-errors.d.ts +126 -0
  249. package/dist/postgres/role-errors.d.ts.map +1 -0
  250. package/dist/postgres/role-membership-sql.d.ts +75 -0
  251. package/dist/postgres/role-membership-sql.d.ts.map +1 -0
  252. package/dist/postgres/role-provider.d.ts +11 -0
  253. package/dist/postgres/role-provider.d.ts.map +1 -0
  254. package/dist/postgres/role-scram.d.ts +6 -0
  255. package/dist/postgres/role-scram.d.ts.map +1 -0
  256. package/dist/postgres/role-secrets.d.ts +30 -0
  257. package/dist/postgres/role-secrets.d.ts.map +1 -0
  258. package/dist/postgres/role-sql.d.ts +68 -0
  259. package/dist/postgres/role-sql.d.ts.map +1 -0
  260. package/dist/postgres/role.d.ts +57 -0
  261. package/dist/postgres/role.d.ts.map +1 -0
  262. package/dist/postgres/schema-assert.d.ts +50 -0
  263. package/dist/postgres/schema-assert.d.ts.map +1 -0
  264. package/dist/postgres/schema-attrs.d.ts +51 -0
  265. package/dist/postgres/schema-attrs.d.ts.map +1 -0
  266. package/dist/postgres/schema-delete.d.ts +28 -0
  267. package/dist/postgres/schema-delete.d.ts.map +1 -0
  268. package/dist/postgres/schema-diff.d.ts +14 -0
  269. package/dist/postgres/schema-diff.d.ts.map +1 -0
  270. package/dist/postgres/schema-errors.d.ts +139 -0
  271. package/dist/postgres/schema-errors.d.ts.map +1 -0
  272. package/dist/postgres/schema-identity.d.ts +8 -0
  273. package/dist/postgres/schema-identity.d.ts.map +1 -0
  274. package/dist/postgres/schema-reconcile.d.ts +12 -0
  275. package/dist/postgres/schema-reconcile.d.ts.map +1 -0
  276. package/dist/postgres/schema-sql.d.ts +45 -0
  277. package/dist/postgres/schema-sql.d.ts.map +1 -0
  278. package/dist/postgres/schema-test-kit.d.ts +67 -0
  279. package/dist/postgres/schema-test-kit.d.ts.map +1 -0
  280. package/dist/postgres/schema.d.ts +54 -0
  281. package/dist/postgres/schema.d.ts.map +1 -0
  282. package/dist/proxmox/ceph-flag-types.d.ts +57 -0
  283. package/dist/proxmox/ceph-flag-types.d.ts.map +1 -0
  284. package/dist/proxmox/ceph-flag-wire.d.ts +77 -0
  285. package/dist/proxmox/ceph-flag-wire.d.ts.map +1 -0
  286. package/dist/proxmox/ceph-flag.d.ts +15 -50
  287. package/dist/proxmox/ceph-flag.d.ts.map +1 -1
  288. package/dist/proxmox/ceph-osd-write.d.ts +10 -13
  289. package/dist/proxmox/ceph-osd-write.d.ts.map +1 -1
  290. package/dist/proxmox/index.js +806 -740
  291. package/dist/proxmox/index.js.map +9 -8
  292. package/dist/release/fake-engine.d.ts +10 -0
  293. package/dist/release/fake-engine.d.ts.map +1 -1
  294. package/dist/release/index.js +35 -1
  295. package/dist/release/index.js.map +3 -3
  296. package/dist/valkey/acl-attrs.d.ts +94 -0
  297. package/dist/valkey/acl-attrs.d.ts.map +1 -0
  298. package/dist/valkey/acl-compare.d.ts +28 -0
  299. package/dist/valkey/acl-compare.d.ts.map +1 -0
  300. package/dist/valkey/acl-connection.d.ts +6 -0
  301. package/dist/valkey/acl-connection.d.ts.map +1 -0
  302. package/dist/valkey/acl-form.d.ts +62 -0
  303. package/dist/valkey/acl-form.d.ts.map +1 -0
  304. package/dist/valkey/acl-managed.d.ts +4 -0
  305. package/dist/valkey/acl-managed.d.ts.map +1 -0
  306. package/dist/valkey/acl-ops.d.ts +37 -0
  307. package/dist/valkey/acl-ops.d.ts.map +1 -0
  308. package/dist/valkey/acl-profiles.d.ts +53 -0
  309. package/dist/valkey/acl-profiles.d.ts.map +1 -0
  310. package/dist/valkey/acl-reconcile.d.ts +26 -0
  311. package/dist/valkey/acl-reconcile.d.ts.map +1 -0
  312. package/dist/valkey/acl.d.ts +24 -0
  313. package/dist/valkey/acl.d.ts.map +1 -0
  314. package/dist/valkey/connection-service.d.ts +22 -0
  315. package/dist/valkey/connection-service.d.ts.map +1 -0
  316. package/dist/valkey/connection.d.ts +59 -0
  317. package/dist/valkey/connection.d.ts.map +1 -0
  318. package/dist/valkey/errors.d.ts +165 -0
  319. package/dist/valkey/errors.d.ts.map +1 -0
  320. package/dist/valkey/fake-acl.d.ts +29 -0
  321. package/dist/valkey/fake-acl.d.ts.map +1 -0
  322. package/dist/valkey/fake-valkey.d.ts +35 -0
  323. package/dist/valkey/fake-valkey.d.ts.map +1 -0
  324. package/dist/valkey/handler-test-fixture.d.ts +20 -0
  325. package/dist/valkey/handler-test-fixture.d.ts.map +1 -0
  326. package/dist/valkey/index.d.ts +18 -0
  327. package/dist/valkey/index.d.ts.map +1 -0
  328. package/dist/valkey/index.js +964 -0
  329. package/dist/valkey/index.js.map +27 -0
  330. package/dist/valkey/instance-attrs.d.ts +46 -0
  331. package/dist/valkey/instance-attrs.d.ts.map +1 -0
  332. package/dist/valkey/instance-form.d.ts +22 -0
  333. package/dist/valkey/instance-form.d.ts.map +1 -0
  334. package/dist/valkey/instance.d.ts +48 -0
  335. package/dist/valkey/instance.d.ts.map +1 -0
  336. package/dist/valkey/provider-socket-fixture.d.ts +8 -0
  337. package/dist/valkey/provider-socket-fixture.d.ts.map +1 -0
  338. package/dist/valkey/providers.d.ts +16 -0
  339. package/dist/valkey/providers.d.ts.map +1 -0
  340. package/dist/valkey/resp.d.ts +38 -0
  341. package/dist/valkey/resp.d.ts.map +1 -0
  342. package/dist/valkey/transport-error.d.ts +36 -0
  343. package/dist/valkey/transport-error.d.ts.map +1 -0
  344. package/dist/valkey/transport.d.ts +50 -0
  345. package/dist/valkey/transport.d.ts.map +1 -0
  346. package/docs/litellm-access-group.md +105 -0
  347. package/docs/litellm-budget.md +55 -0
  348. package/docs/litellm-credential.md +60 -0
  349. package/docs/litellm-key-metadata.md +56 -0
  350. package/docs/litellm-key.md +194 -0
  351. package/docs/litellm-mcp.md +187 -0
  352. package/docs/litellm-model.md +111 -0
  353. package/docs/litellm-policy-attachment.md +86 -0
  354. package/docs/litellm-policy.md +103 -0
  355. package/docs/litellm-team.md +117 -0
  356. package/docs/litellm-tool-policy.md +90 -0
  357. package/docs/litellm-toolset.md +92 -0
  358. package/docs/litellm.md +16 -8
  359. package/docs/peers.md +15 -6
  360. package/docs/postgres-grants-example.md +55 -0
  361. package/docs/postgres-grants.md +157 -0
  362. package/docs/postgres-role.md +114 -0
  363. package/docs/postgres-schema.md +139 -0
  364. package/docs/postgres.md +39 -0
  365. package/docs/proxmox-sdk-migration.md +45 -0
  366. package/docs/valkey-transport.md +29 -0
  367. package/docs/valkey.md +187 -0
  368. package/package.json +7 -3
  369. package/src/litellm/access-group-form.ts +105 -0
  370. package/src/litellm/access-group-operations.ts +92 -0
  371. package/src/litellm/access-group-types.ts +49 -0
  372. package/src/litellm/access-group.test.ts +197 -0
  373. package/src/litellm/access-group.ts +151 -0
  374. package/src/litellm/budget-errors.ts +38 -0
  375. package/src/litellm/budget-form.ts +94 -0
  376. package/src/litellm/budget-operations.ts +51 -0
  377. package/src/litellm/budget.test.ts +105 -0
  378. package/src/litellm/budget.ts +127 -0
  379. package/src/litellm/credential-errors.ts +183 -0
  380. package/src/litellm/credential-form.test.ts +151 -0
  381. package/src/litellm/credential-form.ts +211 -0
  382. package/src/litellm/credential-guards.test.ts +241 -0
  383. package/src/litellm/credential-operations.ts +208 -0
  384. package/src/litellm/credential-recovery.test.ts +93 -0
  385. package/src/litellm/credential-rewrite.test.ts +164 -0
  386. package/src/litellm/credential-rewrite.ts +50 -0
  387. package/src/litellm/credential-types.ts +117 -0
  388. package/src/litellm/credential-values.ts +94 -0
  389. package/src/litellm/credential.test.ts +218 -0
  390. package/src/litellm/credential.ts +227 -0
  391. package/src/litellm/fake-access-group-litellm.ts +127 -0
  392. package/src/litellm/fake-credential-litellm.ts +216 -0
  393. package/src/litellm/fake-keys.ts +190 -0
  394. package/src/litellm/fake-litellm.ts +66 -7
  395. package/src/litellm/fake-mcp-litellm.ts +214 -0
  396. package/src/litellm/fake-model-litellm-post-update.ts +103 -0
  397. package/src/litellm/fake-model-litellm.ts +233 -0
  398. package/src/litellm/fake-policy-attachment-litellm.ts +97 -0
  399. package/src/litellm/fake-policy-litellm.ts +186 -0
  400. package/src/litellm/fake-registry-base.ts +69 -0
  401. package/src/litellm/fake-stack.ts +17 -1
  402. package/src/litellm/fake-team-litellm.ts +229 -0
  403. package/src/litellm/fake-tool-litellm.ts +88 -0
  404. package/src/litellm/fake-toolset-litellm.ts +110 -0
  405. package/src/litellm/index.ts +153 -0
  406. package/src/litellm/key-delete.test.ts +212 -0
  407. package/src/litellm/key-errors.ts +241 -0
  408. package/src/litellm/key-form.ts +200 -0
  409. package/src/litellm/key-harness.ts +121 -0
  410. package/src/litellm/key-metadata-errors.ts +49 -0
  411. package/src/litellm/key-metadata.test.ts +156 -0
  412. package/src/litellm/key-metadata.ts +74 -0
  413. package/src/litellm/key-operations.ts +184 -0
  414. package/src/litellm/key-rotation.test.ts +110 -0
  415. package/src/litellm/key-scope.test.ts +135 -0
  416. package/src/litellm/key-secret.test.ts +248 -0
  417. package/src/litellm/key-secret.ts +137 -0
  418. package/src/litellm/key-transport.test.ts +166 -0
  419. package/src/litellm/key.test.ts +231 -0
  420. package/src/litellm/key.ts +213 -0
  421. package/src/litellm/mcp-server-adopt.test.ts +86 -0
  422. package/src/litellm/mcp-server-alias.test.ts +184 -0
  423. package/src/litellm/mcp-server-credential.ts +85 -0
  424. package/src/litellm/mcp-server-errors.ts +141 -0
  425. package/src/litellm/mcp-server-exports.test.ts +15 -0
  426. package/src/litellm/mcp-server-form.test.ts +241 -0
  427. package/src/litellm/mcp-server-form.ts +233 -0
  428. package/src/litellm/mcp-server-handlers.test.ts +150 -0
  429. package/src/litellm/mcp-server-locate.ts +66 -0
  430. package/src/litellm/mcp-server-operations.ts +111 -0
  431. package/src/litellm/mcp-server-registry.test.ts +146 -0
  432. package/src/litellm/mcp-server-retype.test.ts +114 -0
  433. package/src/litellm/mcp-server-shadow.test.ts +91 -0
  434. package/src/litellm/mcp-server-shadow.ts +45 -0
  435. package/src/litellm/mcp-server-tools.test.ts +85 -0
  436. package/src/litellm/mcp-server-types.ts +143 -0
  437. package/src/litellm/mcp-server-url.ts +66 -0
  438. package/src/litellm/mcp-server.test.ts +213 -0
  439. package/src/litellm/mcp-server.ts +225 -0
  440. package/src/litellm/model-claim.ts +69 -0
  441. package/src/litellm/model-credential.ts +45 -0
  442. package/src/litellm/model-errors.ts +168 -0
  443. package/src/litellm/model-foreign-row.test.ts +173 -0
  444. package/src/litellm/model-form.test.ts +228 -0
  445. package/src/litellm/model-form.ts +223 -0
  446. package/src/litellm/model-locate.test.ts +128 -0
  447. package/src/litellm/model-locate.ts +67 -0
  448. package/src/litellm/model-operations.test.ts +93 -0
  449. package/src/litellm/model-operations.ts +146 -0
  450. package/src/litellm/model-params-preserve.test.ts +119 -0
  451. package/src/litellm/model-recovery.test.ts +57 -0
  452. package/src/litellm/model-types.ts +112 -0
  453. package/src/litellm/model.test.ts +222 -0
  454. package/src/litellm/model.ts +237 -0
  455. package/src/litellm/operations.ts +1 -1
  456. package/src/litellm/policy-attachment-form.ts +103 -0
  457. package/src/litellm/policy-attachment-operations.ts +74 -0
  458. package/src/litellm/policy-attachment-types.ts +48 -0
  459. package/src/litellm/policy-attachment.test.ts +198 -0
  460. package/src/litellm/policy-attachment.ts +178 -0
  461. package/src/litellm/policy-form.ts +122 -0
  462. package/src/litellm/policy-operations.ts +112 -0
  463. package/src/litellm/policy-types.ts +58 -0
  464. package/src/litellm/policy.test.ts +214 -0
  465. package/src/litellm/policy.ts +146 -0
  466. package/src/litellm/providers.ts +25 -1
  467. package/src/litellm/registry-errors.ts +88 -0
  468. package/src/litellm/registry-exports.test.ts +66 -0
  469. package/src/litellm/registry-support.ts +109 -0
  470. package/src/litellm/team-form.ts +140 -0
  471. package/src/litellm/team-members.test.ts +150 -0
  472. package/src/litellm/team-members.ts +58 -0
  473. package/src/litellm/team-operations.ts +90 -0
  474. package/src/litellm/team-permission.ts +159 -0
  475. package/src/litellm/team-read.test.ts +89 -0
  476. package/src/litellm/team-types.ts +106 -0
  477. package/src/litellm/team.test.ts +206 -0
  478. package/src/litellm/team.ts +159 -0
  479. package/src/litellm/tool-policy-form.ts +94 -0
  480. package/src/litellm/tool-policy-operations.ts +58 -0
  481. package/src/litellm/tool-policy-types.ts +48 -0
  482. package/src/litellm/tool-policy.test.ts +172 -0
  483. package/src/litellm/tool-policy.ts +125 -0
  484. package/src/litellm/toolset-form.ts +104 -0
  485. package/src/litellm/toolset-operations.ts +90 -0
  486. package/src/litellm/toolset-types.ts +47 -0
  487. package/src/litellm/toolset.test.ts +198 -0
  488. package/src/litellm/toolset.ts +151 -0
  489. package/src/openbao/auth-role-form.test.ts +37 -0
  490. package/src/openbao/auth-role-form.ts +12 -1
  491. package/src/openbao/auth-role-wire.test.ts +1 -0
  492. package/src/openbao/auth-role-wire.ts +13 -1
  493. package/src/openbao/distilled-retry.test.ts +1 -0
  494. package/src/openbao/fake-engines-roles.ts +7 -1
  495. package/src/ownership/ownership.test.ts +33 -1
  496. package/src/ownership/rows.ts +53 -0
  497. package/src/postgres/connection.ts +72 -3
  498. package/src/postgres/database-bigint-serialization.test.ts +1 -0
  499. package/src/postgres/database-refusals.test.ts +2 -2
  500. package/src/postgres/database-sql.ts +40 -12
  501. package/src/postgres/database.ts +3 -2
  502. package/src/postgres/fake-grants-parse.ts +189 -0
  503. package/src/postgres/fake-grants-read.ts +250 -0
  504. package/src/postgres/fake-grants-sql.ts +207 -0
  505. package/src/postgres/fake-grants-write.ts +90 -0
  506. package/src/postgres/fake-role-sql.ts +220 -0
  507. package/src/postgres/fake-schema-semantics.test.ts +36 -0
  508. package/src/postgres/fake-schema-sql.ts +146 -0
  509. package/src/postgres/fake-sql-parse.ts +86 -0
  510. package/src/postgres/fake-sql-quote.ts +36 -0
  511. package/src/postgres/fake-sql.ts +161 -46
  512. package/src/postgres/fixtures/pg-REL_18_6-acl.h.txt +147 -0
  513. package/src/postgres/fixtures/pg-REL_18_6-aclexplode-func.txt +31 -0
  514. package/src/postgres/fixtures/pg-REL_18_6-alter-default-privileges-synopsis.txt +82 -0
  515. package/src/postgres/fixtures/pg-REL_18_6-alter_role.sgml.txt +44 -0
  516. package/src/postgres/fixtures/pg-REL_18_6-create_role.sgml.txt +26 -0
  517. package/src/postgres/fixtures/pg-REL_18_6-grant-synopsis.txt +95 -0
  518. package/src/postgres/fixtures/pg-REL_18_6-pg_attribute.h.txt +24 -0
  519. package/src/postgres/fixtures/pg-REL_18_6-pg_auth_members.h.txt +62 -0
  520. package/src/postgres/fixtures/pg-REL_18_6-pg_authid.h.txt +70 -0
  521. package/src/postgres/fixtures/pg-REL_18_6-pg_class.h.txt +33 -0
  522. package/src/postgres/fixtures/pg-REL_18_6-pg_default_acl.h.txt +81 -0
  523. package/src/postgres/fixtures/pg-REL_18_6-pg_namespace.h.txt +28 -0
  524. package/src/postgres/fixtures/pg-REL_18_6-revoke-synopsis.txt +124 -0
  525. package/src/postgres/grants-acl.test.ts +61 -0
  526. package/src/postgres/grants-attrs.ts +185 -0
  527. package/src/postgres/grants-database.test.ts +158 -0
  528. package/src/postgres/grants-declare.ts +172 -0
  529. package/src/postgres/grants-delete-proof.test.ts +154 -0
  530. package/src/postgres/grants-diff.ts +101 -0
  531. package/src/postgres/grants-errors.ts +215 -0
  532. package/src/postgres/grants-existence-guards.test.ts +113 -0
  533. package/src/postgres/grants-existence.ts +101 -0
  534. package/src/postgres/grants-lifecycle-guards.test.ts +208 -0
  535. package/src/postgres/grants-lifecycle-repair.test.ts +208 -0
  536. package/src/postgres/grants-lifecycle.test.ts +181 -0
  537. package/src/postgres/grants-ops.ts +229 -0
  538. package/src/postgres/grants-owner-revoke.test.ts +121 -0
  539. package/src/postgres/grants-ownership.ts +49 -0
  540. package/src/postgres/grants-plan-collateral.test.ts +202 -0
  541. package/src/postgres/grants-plan-diff.test.ts +204 -0
  542. package/src/postgres/grants-plan-restore.ts +43 -0
  543. package/src/postgres/grants-plan-revocations.test.ts +69 -0
  544. package/src/postgres/grants-plan.test.ts +148 -0
  545. package/src/postgres/grants-plan.ts +245 -0
  546. package/src/postgres/grants-provenance.test.ts +134 -0
  547. package/src/postgres/grants-psql-lifecycle.test.ts +105 -0
  548. package/src/postgres/grants-read-absent.test.ts +91 -0
  549. package/src/postgres/grants-read-defaults.ts +51 -0
  550. package/src/postgres/grants-read.ts +250 -0
  551. package/src/postgres/grants-refusals.test.ts +136 -0
  552. package/src/postgres/grants-refuse.ts +119 -0
  553. package/src/postgres/grants-relkind-wire.test.ts +111 -0
  554. package/src/postgres/grants-repair-plan.test.ts +201 -0
  555. package/src/postgres/grants-sql.test.ts +128 -0
  556. package/src/postgres/grants-sql.ts +144 -0
  557. package/src/postgres/grants-words.ts +34 -0
  558. package/src/postgres/grants.ts +110 -0
  559. package/src/postgres/index.ts +137 -7
  560. package/src/postgres/installed-classifier.ts +36 -0
  561. package/src/postgres/providers.ts +44 -7
  562. package/src/postgres/psql-executor-escaping.test.ts +67 -0
  563. package/src/postgres/psql-executor.test.ts +167 -0
  564. package/src/postgres/psql-executor.ts +170 -0
  565. package/src/postgres/role-adopt.test.ts +98 -0
  566. package/src/postgres/role-attrs.ts +134 -0
  567. package/src/postgres/role-diff.ts +89 -0
  568. package/src/postgres/role-errors.ts +198 -0
  569. package/src/postgres/role-guard.test.ts +60 -0
  570. package/src/postgres/role-identity.test.ts +185 -0
  571. package/src/postgres/role-lifecycle.test.ts +228 -0
  572. package/src/postgres/role-membership-sql.ts +198 -0
  573. package/src/postgres/role-password.test.ts +158 -0
  574. package/src/postgres/role-privilege.test.ts +80 -0
  575. package/src/postgres/role-provenance.test.ts +200 -0
  576. package/src/postgres/role-provider.ts +104 -0
  577. package/src/postgres/role-refusals.test.ts +250 -0
  578. package/src/postgres/role-scram.test.ts +38 -0
  579. package/src/postgres/role-scram.ts +38 -0
  580. package/src/postgres/role-secrets.ts +46 -0
  581. package/src/postgres/role-sql.ts +211 -0
  582. package/src/postgres/role-valid-until.test.ts +68 -0
  583. package/src/postgres/role.ts +218 -0
  584. package/src/postgres/schema-assert.ts +139 -0
  585. package/src/postgres/schema-attrs.ts +71 -0
  586. package/src/postgres/schema-delete-proofs.test.ts +192 -0
  587. package/src/postgres/schema-delete.ts +96 -0
  588. package/src/postgres/schema-diff.ts +44 -0
  589. package/src/postgres/schema-drop-2bp01.test.ts +146 -0
  590. package/src/postgres/schema-errors.ts +209 -0
  591. package/src/postgres/schema-handlers.test.ts +193 -0
  592. package/src/postgres/schema-identity.ts +39 -0
  593. package/src/postgres/schema-lifecycle.test.ts +246 -0
  594. package/src/postgres/schema-race.test.ts +70 -0
  595. package/src/postgres/schema-reconcile.ts +100 -0
  596. package/src/postgres/schema-refusals.test.ts +144 -0
  597. package/src/postgres/schema-socket.test.ts +161 -0
  598. package/src/postgres/schema-sql.ts +130 -0
  599. package/src/postgres/schema-takeover.test.ts +149 -0
  600. package/src/postgres/schema-test-kit.ts +85 -0
  601. package/src/postgres/schema.ts +130 -0
  602. package/src/proxmox/ceph-flag-types.ts +70 -0
  603. package/src/proxmox/ceph-flag-wire.test.ts +72 -0
  604. package/src/proxmox/ceph-flag-wire.ts +123 -0
  605. package/src/proxmox/ceph-flag.ts +77 -130
  606. package/src/proxmox/ceph-osd-write.ts +10 -13
  607. package/src/release/binary-alias.test.ts +3 -3
  608. package/src/release/binary-claims.test.ts +3 -3
  609. package/src/release/binary-directory-umask.test.ts +65 -0
  610. package/src/release/fake-engine.ts +15 -0
  611. package/src/valkey/acl-attrs.ts +98 -0
  612. package/src/valkey/acl-compare.ts +57 -0
  613. package/src/valkey/acl-connection.ts +13 -0
  614. package/src/valkey/acl-delete.test.ts +127 -0
  615. package/src/valkey/acl-form.ts +239 -0
  616. package/src/valkey/acl-managed.ts +13 -0
  617. package/src/valkey/acl-ops.ts +122 -0
  618. package/src/valkey/acl-ownership.test.ts +118 -0
  619. package/src/valkey/acl-prefix.test.ts +38 -0
  620. package/src/valkey/acl-profiles.ts +81 -0
  621. package/src/valkey/acl-reconcile.ts +180 -0
  622. package/src/valkey/acl-reserved.test.ts +69 -0
  623. package/src/valkey/acl-revocation.test.ts +94 -0
  624. package/src/valkey/acl-seat-prefix.test.ts +111 -0
  625. package/src/valkey/acl-validation.test.ts +54 -0
  626. package/src/valkey/acl.test.ts +215 -0
  627. package/src/valkey/acl.ts +169 -0
  628. package/src/valkey/connection-service.ts +46 -0
  629. package/src/valkey/connection.ts +180 -0
  630. package/src/valkey/errors.ts +239 -0
  631. package/src/valkey/fake-acl.ts +128 -0
  632. package/src/valkey/fake-valkey.ts +224 -0
  633. package/src/valkey/handler-test-fixture.ts +43 -0
  634. package/src/valkey/handlers.test.ts +205 -0
  635. package/src/valkey/index.ts +54 -0
  636. package/src/valkey/instance-attrs.ts +48 -0
  637. package/src/valkey/instance-form.ts +104 -0
  638. package/src/valkey/instance.test.ts +108 -0
  639. package/src/valkey/instance.ts +160 -0
  640. package/src/valkey/provider-socket-fixture.ts +71 -0
  641. package/src/valkey/providers.test.ts +129 -0
  642. package/src/valkey/providers.ts +21 -0
  643. package/src/valkey/resp.ts +212 -0
  644. package/src/valkey/transport-bounds.test.ts +150 -0
  645. package/src/valkey/transport-error.ts +37 -0
  646. package/src/valkey/transport.test.ts +158 -0
  647. package/src/valkey/transport.ts +109 -0
  648. package/src/valkey/upstream-bounds.test.ts +14 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * `LiteLLM.Budget` through Alchemy's real Plan and Apply over the fake proxy.
3
+ */
4
+ import { expect, test } from 'bun:test';
5
+ import * as Effect from 'effect/Effect';
6
+ import { FAKE_BASE, startFakeLitellm } from './fake-litellm.ts';
7
+ import { fakeStack, writesOf } from './fake-stack.ts';
8
+ import { type BudgetProps, LiteLLMBudget } from './budget.ts';
9
+ import { differing, isHardCapUnjustified, toAttributes } from './budget-form.ts';
10
+
11
+ const KEY = 'sk-test-master';
12
+ const stack = (fake: ReturnType<typeof startFakeLitellm>) =>
13
+ fakeStack({ apiKey: KEY, baseUrl: FAKE_BASE }, fake.fetch);
14
+ const declare = (props: BudgetProps, name = 'Tier') =>
15
+ Effect.gen(function* () {
16
+ yield* LiteLLMBudget(name, props);
17
+ });
18
+
19
+ const tier = {
20
+ budget_id: 'hf-tier-agent',
21
+ budget_duration: '1d',
22
+ created_at: 'x',
23
+ max_budget: 2,
24
+ rpm_limit: '60',
25
+ soft_budget: null,
26
+ tpm_limit: null,
27
+ updated_at: 'x',
28
+ };
29
+
30
+ test('creates a soft-only budget and sends no max_budget', async () => {
31
+ const fake = startFakeLitellm({ masterKey: KEY });
32
+ const planned = await stack(fake).deploy(
33
+ declare({ budgetId: 'hf-tier-x', budgetDuration: '1d', softBudget: 50 }),
34
+ );
35
+ expect(planned).toEqual({ Tier: 'create' });
36
+ expect(fake.budgets()[0]).toMatchObject({ budget_id: 'hf-tier-x', soft_budget: 50 });
37
+ expect(fake.budgets()[0]).not.toHaveProperty('max_budget');
38
+ });
39
+
40
+ test('a second deploy of the same declaration writes nothing', async () => {
41
+ const fake = startFakeLitellm({ masterKey: KEY });
42
+ const props = { budgetId: 'hf-tier-x', softBudget: 50, rpmLimit: 60 };
43
+ const same = stack(fake);
44
+ await same.deploy(declare(props));
45
+ const before = fake.requests().length;
46
+ expect(await same.deploy(declare(props))).toEqual({ Tier: 'noop' });
47
+ expect(writesOf(fake.requests().slice(before))).toEqual([]);
48
+ });
49
+
50
+ test('a hard cap without a reason is refused before any write', async () => {
51
+ const fake = startFakeLitellm({ masterKey: KEY });
52
+ await expect(
53
+ stack(fake).deploy(declare({ budgetId: 'hf-tier-x', maxBudget: 60 })),
54
+ ).rejects.toThrow();
55
+ expect(writesOf(fake.requests())).toEqual([]);
56
+ expect(isHardCapUnjustified({ maxBudget: 1, maxBudgetReason: ' ' })).toBe(true);
57
+ expect(isHardCapUnjustified({ maxBudget: 1, maxBudgetReason: 'abuse guard' })).toBe(false);
58
+ });
59
+
60
+ test('a hard cap with a reason is written', async () => {
61
+ const fake = startFakeLitellm({ masterKey: KEY });
62
+ await stack(fake).deploy(
63
+ declare({ budgetId: 'hf-tier-x', maxBudget: 5, maxBudgetReason: 'public voice endpoint' }),
64
+ );
65
+ expect(fake.budgets()[0]).toMatchObject({ max_budget: 5 });
66
+ });
67
+
68
+ test('a live row is Unowned: refused without --adopt, taken with it', async () => {
69
+ const fake = startFakeLitellm({ masterKey: KEY, budgetSeed: [tier] });
70
+ const props = {
71
+ budgetId: 'hf-tier-agent',
72
+ budgetDuration: '1d',
73
+ maxBudget: 2,
74
+ maxBudgetReason: 'measured live',
75
+ };
76
+ const engine = stack(fake);
77
+ await expect(engine.deploy(declare(props))).rejects.toThrow();
78
+ expect(writesOf(fake.requests())).toEqual([]);
79
+ const planned = await engine.deploy(declare({ ...props, rpmLimit: 60 }), { adopt: true });
80
+ expect(Object.values(planned)).toEqual(['adopted']);
81
+ });
82
+
83
+ test('adopting a hard tier and declaring it soft clears max_budget', async () => {
84
+ const fake = startFakeLitellm({ masterKey: KEY, budgetSeed: [tier] });
85
+ await stack(fake).deploy(
86
+ declare({ budgetId: 'hf-tier-agent', budgetDuration: '1d', rpmLimit: 60, softBudget: 2 }),
87
+ { adopt: true },
88
+ );
89
+ expect(fake.budgets()[0]).toMatchObject({ max_budget: null, soft_budget: 2 });
90
+ });
91
+
92
+ test('a proxy that cannot clear a limit fails the apply instead of claiming success', async () => {
93
+ const fake = startFakeLitellm({ masterKey: KEY, budgetSeed: [tier], budgetExcludeNone: true });
94
+ await expect(
95
+ stack(fake).deploy(declare({ budgetId: 'hf-tier-agent', budgetDuration: '1d', rpmLimit: 60 }), {
96
+ adopt: true,
97
+ }),
98
+ ).rejects.toThrow();
99
+ });
100
+
101
+ test('form helpers: string limits become numbers, and differences are named', () => {
102
+ const live = toAttributes(tier);
103
+ expect(live.rpmLimit).toBe(60);
104
+ expect(differing(live, { budgetDuration: '1d', rpmLimit: 60 })).toEqual(['max_budget']);
105
+ });
@@ -0,0 +1,127 @@
1
+ /**
2
+ * `LiteLLM.Budget` — one row of LiteLLM's `LiteLLM_BudgetTable` (`/budget/*`), the "tier" keys and
3
+ * teams bind to (`hf-tier-*`).
4
+ *
5
+ * ★ MONITORING, NOT LIMITS (Tim, 2026-09-28): `softBudget` is the prop; `maxBudget` is a hard cap
6
+ * that 429s every caller and is refused without `maxBudgetReason` (budget-form.ts).
7
+ * ★ ADOPT BY id. `budgetId` names the live row; without it a deterministic physical name is used.
8
+ * A foreign row with that id is `Unowned`, so it needs `--adopt`.
9
+ * ★ `defaultRemovalPolicy: 'retain'` — deleting a budget row that keys still reference either
10
+ * fails or detaches them, and a detached key loses its rate limits. Opt in with
11
+ * `.pipe(RemovalPolicy.destroy())`.
12
+ * ⛔ CLEARING A LIMIT: sent as an explicit `null`. If this LiteLLM merges with `exclude_none` the
13
+ * row keeps the old value; reconcile reads back and FAILS (`LitellmBudgetFieldNotClearedError`)
14
+ * rather than report a cleared cap. Unmeasured against a live proxy at 1.103.0.
15
+ * ⛔ NO CREDENTIAL IS A PROP; `litellmProviders`' layer supplies `Credentials`.
16
+ */
17
+ import { Resource } from 'alchemy';
18
+ import { Unowned } from 'alchemy/AdoptPolicy';
19
+ import { isResolved } from 'alchemy/Diff';
20
+ import type { Input } from 'alchemy/Input';
21
+ import { createPhysicalName } from 'alchemy/PhysicalName';
22
+ import * as Provider from 'alchemy/Provider';
23
+ import * as Effect from 'effect/Effect';
24
+ import * as Predicate from 'effect/Predicate';
25
+ import {
26
+ LitellmBudgetFieldNotClearedError,
27
+ LitellmBudgetHardCapUnjustifiedError,
28
+ } from './budget-errors.ts';
29
+ import {
30
+ type BudgetAttributes,
31
+ type BudgetProps,
32
+ createBody,
33
+ differing,
34
+ isHardCapUnjustified,
35
+ updateBody,
36
+ } from './budget-form.ts';
37
+ import { createBudget, deleteBudget, listBudgets, updateBudget } from './budget-operations.ts';
38
+
39
+ export type { BudgetAttributes, BudgetProps };
40
+ export type { BudgetError } from './budget-errors.ts';
41
+
42
+ export interface LiteLLMBudget extends Resource<'LiteLLM.Budget', BudgetProps, BudgetAttributes> {}
43
+
44
+ export const LiteLLMBudget = Resource<LiteLLMBudget>('LiteLLM.Budget', {
45
+ defaultRemovalPolicy: 'retain',
46
+ });
47
+
48
+ export const isLiteLLMBudget = (value: unknown): value is LiteLLMBudget =>
49
+ Predicate.hasProperty(value, 'Type') && value.Type === 'LiteLLM.Budget';
50
+
51
+ const refuseUnjustifiedCap = (props: BudgetProps) =>
52
+ isHardCapUnjustified(props)
53
+ ? Effect.fail(new LitellmBudgetHardCapUnjustifiedError({ budgetId: props.budgetId }))
54
+ : Effect.void;
55
+
56
+ const idOf = (
57
+ id: string,
58
+ instanceId: string,
59
+ props: BudgetProps,
60
+ output: BudgetAttributes | undefined,
61
+ ) =>
62
+ output?.budgetId !== undefined
63
+ ? Effect.succeed(output.budgetId)
64
+ : props.budgetId !== undefined
65
+ ? Effect.succeed(props.budgetId)
66
+ : createPhysicalName({ id, instanceId, lowercase: true, maxLength: 64 });
67
+
68
+ type Args<P> = {
69
+ id: string;
70
+ instanceId: string;
71
+ output: BudgetAttributes | undefined;
72
+ } & P;
73
+
74
+ /** ⛔ TEST-ONLY EXPORT. Not on index.ts's barrel. */
75
+ export const budgetHandlers = {
76
+ read: ({ id, instanceId, olds, output }: Args<{ olds: BudgetProps }>) =>
77
+ Effect.gen(function* () {
78
+ const budgetId = yield* idOf(id, instanceId, olds, output);
79
+ const live = (yield* listBudgets()).find((row) => row.budgetId === budgetId);
80
+ if (live === undefined) return undefined;
81
+ return output === undefined ? Unowned(live) : live;
82
+ }),
83
+
84
+ diff: ({ news, output }: { news: Input<BudgetProps>; output: BudgetAttributes | undefined }) =>
85
+ Effect.gen(function* () {
86
+ if (!isResolved(news)) return undefined;
87
+ yield* refuseUnjustifiedCap(news);
88
+ if (output === undefined) return undefined;
89
+ // The id is identity: a different declared id is a different row.
90
+ if (news.budgetId !== undefined && news.budgetId !== output.budgetId) {
91
+ return { action: 'replace', deleteFirst: false } as const;
92
+ }
93
+ return differing(output, news).length === 0
94
+ ? ({ action: 'noop' } as const)
95
+ : ({ action: 'update' } as const);
96
+ }),
97
+
98
+ reconcile: ({ id, instanceId, news, output }: Args<{ news: BudgetProps }>) =>
99
+ Effect.gen(function* () {
100
+ yield* refuseUnjustifiedCap(news);
101
+ const budgetId = yield* idOf(id, instanceId, news, output);
102
+ const before = (yield* listBudgets()).find((row) => row.budgetId === budgetId);
103
+ if (before === undefined) yield* createBudget(createBody(news, budgetId));
104
+ else if (differing(before, news).length > 0) yield* updateBudget(updateBody(news, before));
105
+
106
+ const after = (yield* listBudgets()).find((row) => row.budgetId === budgetId);
107
+ if (after === undefined) {
108
+ return yield* Effect.die(
109
+ new Error(`LiteLLM.Budget ${budgetId}: write returned no error but the row is absent.`),
110
+ );
111
+ }
112
+ const left = differing(after, news);
113
+ if (left.length > 0) {
114
+ return yield* Effect.fail(
115
+ new LitellmBudgetFieldNotClearedError({ budgetId, fields: left }),
116
+ );
117
+ }
118
+ return after;
119
+ }),
120
+
121
+ delete: ({ output }: { output: BudgetAttributes }) => deleteBudget(output.budgetId),
122
+
123
+ list: () => Effect.succeed([]),
124
+ };
125
+
126
+ export const LiteLLMBudgetProvider = () =>
127
+ Provider.effect(LiteLLMBudget, Effect.succeed(LiteLLMBudget.Provider.of(budgetHandlers)));
@@ -0,0 +1,183 @@
1
+ /**
2
+ * The typed refusals `LiteLLM.Credential` raises on top of `@distilled.cloud/litellm`'s own SDK
3
+ * errors.
4
+ *
5
+ * ⛔ NO MESSAGE HERE MAY CARRY A CREDENTIAL VALUE: only the credential's NAME, field names, the
6
+ * NAMES of environment variables, and SDK error text — exactly like mcp-server-errors.ts.
7
+ * ⚠️ THE SDK'S TYPED UNION IS NARROW ON PURPOSE, and the runtime is wider: the credential routes
8
+ * declare only `UnprocessableEntity` (422) in `credential_management.ts`, so a create on an
9
+ * existing name — which the live 1.103.0 container answers `409` (`endpoints.py`'s
10
+ * `_credential_exists_detail`) — decodes at run time as the core `Conflict` class (`Errors.ts`
11
+ * re-exports it, but it is not in the operation's TS union) and PROPAGATES as such, never
12
+ * silently swallowed (S21). The read's and delete's `404` is TYPED as the SDK's
13
+ * `CredentialNotFound` (a distilled patch matched on the vendor's "Credential not found"
14
+ * message, `endpoints.py`), so credential-operations.ts `catchTag`s it instead of `instanceof`
15
+ * `NotFound`: a 404 from a front proxy, Access, or a wrong base path stays a `NotFound` and is
16
+ * never read as absence. `CredentialError` carries the typed members of the four operations the
17
+ * resource calls (create, by-name read, PATCH, delete), plus the refusals below.
18
+ */
19
+ import type * as credentials from '@distilled.cloud/litellm/credential_management';
20
+ import * as Data from 'effect/Data';
21
+ import type { HttpClientErrorReason } from 'effect/unstable/http/HttpClientError';
22
+
23
+ /** A declaration the resource refuses before any request: a combination nobody meant. */
24
+ export class LitellmCredentialInvalidError extends Data.TaggedError(
25
+ 'LitellmCredentialInvalidError',
26
+ )<{
27
+ readonly credentialName: string;
28
+ readonly problem: string;
29
+ }> {
30
+ override get message(): string {
31
+ return `LiteLLM.Credential "${this.credentialName}": ${this.problem}.`;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * A create's `POST /credentials` or an update's `PATCH /credentials/{name}` failed on the wire (or
37
+ * its answer could not be read), so nobody knows whether the credential is what was asked for.
38
+ *
39
+ * ⛔ THIS IS WHAT STANDS IN FOR AN `HttpClientError`, WHICH CARRIES ITS REQUEST, AND THE REQUEST
40
+ * BODY OF A CREATE OR UPDATE IS `{"credential_name": …, "credential_values": {"api_key": "…"}}`.
41
+ * Measured 2026-09-30: on a dropped connection `JSON.stringify(error)`, `Bun.inspect(error)` and
42
+ * Effect's JSON logger all printed the value, as did a failed deploy over it — the same leak
43
+ * key-operations.ts's `LitellmKeyTransportError` closes. A defect reading a broken answer
44
+ * (`protocol-rest.ts` reads it `Effect.orDie`) carries the same request. So `reason` keeps the
45
+ * `HttpClientError` reason's TAG (a string) and nothing else: no request, no cause, no
46
+ * description. The credential NAME stays — it is not secret.
47
+ */
48
+ export class LitellmCredentialTransportError extends Data.TaggedError(
49
+ 'LitellmCredentialTransportError',
50
+ )<{
51
+ readonly credentialName: string;
52
+ readonly reason: HttpClientErrorReason['_tag'] | 'Defect';
53
+ }> {
54
+ override get message(): string {
55
+ return (
56
+ `LiteLLM.Credential "${this.credentialName}": a /credentials write failed ` +
57
+ `(${this.reason}) before an answer could be read, so the credential MAY have been written. ` +
58
+ 'This error keeps neither the request nor its cause: the request body holds the credential ' +
59
+ 'values. Look the name up in LiteLLM. A row that landed is taken over by the next deploy ' +
60
+ 'with --adopt; one that did not is created by it.'
61
+ );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * The SDK prints request and response bodies to stderr while `DISTILLED_DEBUG_HTTP` is set, and a
67
+ * `POST /credentials` carries the values in its body — refused before any request, exactly like
68
+ * `key-secret.ts`'s `refuseDebugLogging` for `/key/generate`.
69
+ */
70
+ export class LitellmCredentialDebugLoggingError extends Data.TaggedError(
71
+ 'LitellmCredentialDebugLoggingError',
72
+ )<{
73
+ readonly credentialName: string;
74
+ }> {
75
+ override get message(): string {
76
+ return (
77
+ `LiteLLM.Credential "${this.credentialName}": DISTILLED_DEBUG_HTTP is set, so the SDK ` +
78
+ "would print the credential values to stderr in /credentials' request and response. Unset " +
79
+ 'it and run again. Nothing was written.'
80
+ );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * A write had to send the credential values and the deploying process does not hold one or more
86
+ * of the declared variables. The names are listed, never a value.
87
+ */
88
+ export class LitellmCredentialEnvUnsetError extends Data.TaggedError(
89
+ 'LitellmCredentialEnvUnsetError',
90
+ )<{
91
+ readonly credentialName: string;
92
+ readonly variables: readonly string[];
93
+ }> {
94
+ override get message(): string {
95
+ return (
96
+ `LiteLLM.Credential "${this.credentialName}": ` +
97
+ `the deploying process does not set ${this.variables.join(', ')}.`
98
+ );
99
+ }
100
+ }
101
+
102
+ /**
103
+ * A credentials read answered something that is not a row of the credential table (or named a
104
+ * different row), so adopt-by-name cannot trust it. The by-name read is this resource's only
105
+ * read, so a row it cannot recognise is refused rather than guessed at.
106
+ */
107
+ export class LitellmCredentialUnreadableError extends Data.TaggedError(
108
+ 'LitellmCredentialUnreadableError',
109
+ )<{
110
+ readonly reason: string;
111
+ }> {
112
+ override get message(): string {
113
+ return `LiteLLM.Credential: a credentials read is unreadable (${this.reason}).`;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * A create or update returned no error, yet the by-name read does not answer the credential — the
119
+ * proxy failed to record it in memory or in the DB. Refused instead of reported as done.
120
+ */
121
+ export class LitellmCredentialAbsentAfterWriteError extends Data.TaggedError(
122
+ 'LitellmCredentialAbsentAfterWriteError',
123
+ )<{
124
+ readonly credentialName: string;
125
+ }> {
126
+ override get message(): string {
127
+ return (
128
+ `LiteLLM.Credential "${this.credentialName}": the write returned no error but the ` +
129
+ 'credential is absent from the by-name read.'
130
+ );
131
+ }
132
+ }
133
+
134
+ /**
135
+ * The write returned no error but the credential still differs from the declaration. The update
136
+ * path this resource uses is a PATCH merge (credential.ts, credential-operations.ts) — or a
137
+ * whole-row rewrite to drop a key — so a residual difference is refused here instead of being
138
+ * reported as converged.
139
+ */
140
+ export class LitellmCredentialNotConvergedError extends Data.TaggedError(
141
+ 'LitellmCredentialNotConvergedError',
142
+ )<{
143
+ readonly credentialName: string;
144
+ readonly fields: readonly string[];
145
+ }> {
146
+ override get message(): string {
147
+ return (
148
+ `LiteLLM.Credential "${this.credentialName}": after the write it still differs from the ` +
149
+ `declaration in ${this.fields.join(', ')}.`
150
+ );
151
+ }
152
+ }
153
+
154
+ /** A rewrite deleted the old row before its POST failed. Keep only the failure tag. */
155
+ export class LitellmCredentialRewriteError extends Data.TaggedError(
156
+ 'LitellmCredentialRewriteError',
157
+ )<{
158
+ readonly credentialName: string;
159
+ readonly reason: string;
160
+ }> {
161
+ override get message(): string {
162
+ return (
163
+ `LiteLLM.Credential "${this.credentialName}": DELETE already ran, but the replacement ` +
164
+ `POST failed (${this.reason}). The next deploy recreates the row if absent; keep all ` +
165
+ 'declared credential variables set. If the POST landed despite the failure, the next ' +
166
+ 'deploy reads and reconciles that row.'
167
+ );
168
+ }
169
+ }
170
+
171
+ export type CredentialError =
172
+ | credentials.CreateCredentialCredentialsPostError
173
+ | credentials.GetCredentialByNameCredentialsByNameCredentialNameGetError
174
+ | credentials.UpdateCredentialCredentialsCredentialNamePatchError
175
+ | credentials.DeleteCredentialCredentialsCredentialNameDeleteError
176
+ | LitellmCredentialInvalidError
177
+ | LitellmCredentialTransportError
178
+ | LitellmCredentialRewriteError
179
+ | LitellmCredentialDebugLoggingError
180
+ | LitellmCredentialEnvUnsetError
181
+ | LitellmCredentialUnreadableError
182
+ | LitellmCredentialAbsentAfterWriteError
183
+ | LitellmCredentialNotConvergedError;
@@ -0,0 +1,151 @@
1
+ /**
2
+ * `credential-form.ts`'s refusals, read shape and comparison — pure: no server, no environment
3
+ * (the values' own behaviour is credential-values.ts's, tested through the resource test).
4
+ *
5
+ * ★ EVERY VALUE IS `FAKE-*`.
6
+ */
7
+ import { expect, test } from 'bun:test';
8
+ import * as Redacted from 'effect/Redacted';
9
+ import {
10
+ createBody,
11
+ differing,
12
+ firstProblem,
13
+ isCredentialRow,
14
+ literalValues,
15
+ patchBody,
16
+ removedInfoKeys,
17
+ toAttributes,
18
+ } from './credential-form.ts';
19
+ import type { CredentialAttributes, CredentialProps } from './credential-types.ts';
20
+ import type { ResolvedValues } from './credential-values.ts';
21
+
22
+ const VARIABLE = 'FAKE_CREDENTIAL_KEY';
23
+ const base: CredentialProps = {
24
+ credentialInfo: { note: 'docs search' },
25
+ credentialName: 'FAKE_api',
26
+ credentialValues: { api_key: { fromEnv: VARIABLE } },
27
+ };
28
+
29
+ /** Live attributes as the resource would hold them, over a metadata map. */
30
+ const attributes = (info: Record<string, unknown>, seal = ''): CredentialAttributes => ({
31
+ credentialInfo: info,
32
+ credentialName: 'FAKE_api',
33
+ valuesSeal: seal,
34
+ });
35
+
36
+ test('firstProblem refuses the combinations nobody meant', () => {
37
+ const cases: readonly [label: string, props: CredentialProps, fragment: string][] = [
38
+ ['a blank name', { ...base, credentialName: ' ' }, 'credentialName'],
39
+ ['a padded name', { ...base, credentialName: ' FAKE_api' }, 'credentialName'],
40
+ ['a non-object metadata map', { ...base, credentialInfo: null as never }, 'credentialInfo'],
41
+ [
42
+ 'a sensitive metadata key',
43
+ { ...base, credentialInfo: { authToken: 'FAKE-meta' } },
44
+ 'authToken',
45
+ ],
46
+ ['an empty values map', { ...base, credentialValues: {} }, 'credentialValues'],
47
+ [
48
+ 'a padded values key',
49
+ { ...base, credentialValues: { ' key': { fromEnv: VARIABLE } } },
50
+ 'credentialValues',
51
+ ],
52
+ [
53
+ 'a literal value',
54
+ { ...base, credentialValues: { api_key: 'FAKE-literal' as never } },
55
+ 'credentialValues',
56
+ ],
57
+ [
58
+ 'a blank variable name',
59
+ { ...base, credentialValues: { api_key: { fromEnv: ' ' } } },
60
+ 'credentialValues',
61
+ ],
62
+ ];
63
+ for (const [label, props, fragment] of cases) {
64
+ expect(firstProblem(props), label).toContain(fragment);
65
+ }
66
+ expect(firstProblem(base)).toBeUndefined();
67
+ });
68
+
69
+ test('toAttributes mirrors only the metadata the vendor answers unmasked, and no values at all', () => {
70
+ const live = toAttributes({
71
+ credential_info: { note: 'docs search', aws_secret: 'FAKE-clear-in-info' },
72
+ credential_name: 'FAKE_api',
73
+ credential_values: { api_key: 'FA****ey', region: 'us-east' },
74
+ });
75
+ expect(live).toEqual({
76
+ credentialInfo: { note: 'docs search' },
77
+ credentialName: 'FAKE_api',
78
+ valueKeys: ['api_key', 'region'],
79
+ infoKeys: ['aws_secret', 'note'],
80
+ valuesSeal: '',
81
+ });
82
+ });
83
+
84
+ test('differing compares per declared key only, deeply, ignoring object key order', () => {
85
+ // This helper checks declared values; removedInfoKeys separately detects undeclared live keys.
86
+ expect(differing(attributes({ note: 'docs search', extra: 'live' }), base)).toEqual([]);
87
+ expect(differing(attributes({ note: 'docs search v2', extra: 'live' }), base)).toEqual([
88
+ 'credential_info.note',
89
+ ]);
90
+ expect(differing(attributes({}), base)).toEqual(['credential_info.note']);
91
+ const nested = { ...base, credentialInfo: { scopes: ['read', 'write'], vendor: { a: 1, b: 2 } } };
92
+ // object key order never matters; array order does — an array is an ordered list in JSON
93
+ expect(
94
+ differing(attributes({ scopes: ['read', 'write'], vendor: { b: 2, a: 1 } }), nested),
95
+ ).toEqual([]);
96
+ expect(
97
+ differing(attributes({ scopes: ['write', 'read'], vendor: { a: 1, b: 2 } }), nested),
98
+ ).toEqual(['credential_info.scopes']);
99
+ expect(differing(attributes({ scopes: ['read'], vendor: { a: 1, b: 2 } }), nested)).toEqual([
100
+ 'credential_info.scopes',
101
+ ]);
102
+ });
103
+
104
+ test('isCredentialRow accepts only a row with a string name', () => {
105
+ expect(isCredentialRow({ credential_name: 'FAKE_api' })).toBe(true);
106
+ expect(isCredentialRow({ credential_values: {} })).toBe(false);
107
+ expect(isCredentialRow('not a row')).toBe(false);
108
+ expect(isCredentialRow(null)).toBe(false);
109
+ });
110
+
111
+ test('createBody carries the name in the body and the values as literals, unwrapped once', () => {
112
+ const resolved: ResolvedValues = {
113
+ missing: [],
114
+ values: { api_key: Redacted.make('FAKE-key-one') },
115
+ };
116
+ expect(literalValues(resolved)).toEqual({ api_key: 'FAKE-key-one' });
117
+ const body = createBody(base, resolved);
118
+ expect(body).toEqual({
119
+ credential_info: { note: 'docs search' },
120
+ credential_name: 'FAKE_api',
121
+ credential_values: { api_key: 'FAKE-key-one' },
122
+ });
123
+ // the body carries the VALUE the proxy stores, never the variable NAME the declaration holds
124
+ expect(JSON.stringify(body)).not.toContain(VARIABLE);
125
+ });
126
+
127
+ test('patchBody carries the name twice (path label and body field) and the info, values optional', () => {
128
+ expect(patchBody(base, undefined)).toEqual({
129
+ credential_info: { note: 'docs search' },
130
+ credential_name: 'FAKE_api',
131
+ credential_name_body: 'FAKE_api',
132
+ });
133
+ expect(patchBody(base, { api_key: 'FAKE-key-one' })).toEqual({
134
+ credential_info: { note: 'docs search' },
135
+ credential_name: 'FAKE_api',
136
+ credential_name_body: 'FAKE_api',
137
+ credential_values: { api_key: 'FAKE-key-one' },
138
+ });
139
+ // the body carries the VALUE, never the variable NAME the declaration holds
140
+ expect(JSON.stringify(patchBody(base, { api_key: 'FAKE-key-one' }))).not.toContain(VARIABLE);
141
+ });
142
+
143
+ test('removedInfoKeys finds live keys absent from the full intended info map', () => {
144
+ const prior = attributes({ note: 'docs search', team: 'a' });
145
+ expect(removedInfoKeys(prior, base)).toEqual(['team']);
146
+ expect(
147
+ removedInfoKeys(prior, { ...base, credentialInfo: { note: 'docs search', team: 'a' } }),
148
+ ).toEqual([]);
149
+ // No live row means there is nothing to remove.
150
+ expect(removedInfoKeys(undefined, base)).toEqual([]);
151
+ });