@acquiredintelligence/attend 0.0.0-stage → 0.2.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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -2
  3. package/dist/attend.d.ts +30 -0
  4. package/dist/attend.d.ts.map +1 -0
  5. package/dist/attend.js +464 -0
  6. package/dist/attend.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +4 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/core/ids.d.ts +12 -0
  12. package/dist/core/ids.d.ts.map +1 -0
  13. package/dist/core/ids.js +97 -0
  14. package/dist/core/ids.js.map +1 -0
  15. package/dist/core/reducer.d.ts +26 -0
  16. package/dist/core/reducer.d.ts.map +1 -0
  17. package/dist/core/reducer.js +437 -0
  18. package/dist/core/reducer.js.map +1 -0
  19. package/dist/core/seen.d.ts +22 -0
  20. package/dist/core/seen.d.ts.map +1 -0
  21. package/dist/core/seen.js +61 -0
  22. package/dist/core/seen.js.map +1 -0
  23. package/dist/core/state.d.ts +12 -0
  24. package/dist/core/state.d.ts.map +1 -0
  25. package/dist/core/state.js +90 -0
  26. package/dist/core/state.js.map +1 -0
  27. package/dist/core/step.d.ts +14 -0
  28. package/dist/core/step.d.ts.map +1 -0
  29. package/dist/core/step.js +17 -0
  30. package/dist/core/step.js.map +1 -0
  31. package/dist/core/threshold.d.ts +40 -0
  32. package/dist/core/threshold.d.ts.map +1 -0
  33. package/dist/core/threshold.js +72 -0
  34. package/dist/core/threshold.js.map +1 -0
  35. package/dist/core/types.d.ts +704 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +24 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/window.d.ts +38 -0
  40. package/dist/core/window.d.ts.map +1 -0
  41. package/dist/core/window.js +322 -0
  42. package/dist/core/window.js.map +1 -0
  43. package/dist/decisions.d.ts +53 -0
  44. package/dist/decisions.d.ts.map +1 -0
  45. package/dist/decisions.js +115 -0
  46. package/dist/decisions.js.map +1 -0
  47. package/dist/errors.d.ts +36 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +53 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/internal/adapter.d.ts +21 -0
  56. package/dist/internal/adapter.d.ts.map +1 -0
  57. package/dist/internal/adapter.js +62 -0
  58. package/dist/internal/adapter.js.map +1 -0
  59. package/dist/internal/assert.d.ts +5 -0
  60. package/dist/internal/assert.d.ts.map +1 -0
  61. package/dist/internal/assert.js +14 -0
  62. package/dist/internal/assert.js.map +1 -0
  63. package/dist/internal/clock.d.ts +8 -0
  64. package/dist/internal/clock.d.ts.map +1 -0
  65. package/dist/internal/clock.js +38 -0
  66. package/dist/internal/clock.js.map +1 -0
  67. package/dist/internal/http.d.ts +42 -0
  68. package/dist/internal/http.d.ts.map +1 -0
  69. package/dist/internal/http.js +122 -0
  70. package/dist/internal/http.js.map +1 -0
  71. package/dist/internal/images.d.ts +18 -0
  72. package/dist/internal/images.d.ts.map +1 -0
  73. package/dist/internal/images.js +75 -0
  74. package/dist/internal/images.js.map +1 -0
  75. package/dist/internal/json.d.ts +3 -0
  76. package/dist/internal/json.d.ts.map +1 -0
  77. package/dist/internal/json.js +5 -0
  78. package/dist/internal/json.js.map +1 -0
  79. package/dist/internal/prompt.d.ts +31 -0
  80. package/dist/internal/prompt.d.ts.map +1 -0
  81. package/dist/internal/prompt.js +149 -0
  82. package/dist/internal/prompt.js.map +1 -0
  83. package/dist/internal/shared.d.ts +12 -0
  84. package/dist/internal/shared.d.ts.map +1 -0
  85. package/dist/internal/shared.js +138 -0
  86. package/dist/internal/shared.js.map +1 -0
  87. package/dist/jev.d.ts +74 -0
  88. package/dist/jev.d.ts.map +1 -0
  89. package/dist/jev.js +156 -0
  90. package/dist/jev.js.map +1 -0
  91. package/dist/llm.d.ts +164 -0
  92. package/dist/llm.d.ts.map +1 -0
  93. package/dist/llm.js +79 -0
  94. package/dist/llm.js.map +1 -0
  95. package/dist/mcp.d.ts +130 -0
  96. package/dist/mcp.d.ts.map +1 -0
  97. package/dist/mcp.js +550 -0
  98. package/dist/mcp.js.map +1 -0
  99. package/dist/memory.d.ts +10 -0
  100. package/dist/memory.d.ts.map +1 -0
  101. package/dist/memory.js +50 -0
  102. package/dist/memory.js.map +1 -0
  103. package/dist/postgres.d.ts +25 -0
  104. package/dist/postgres.d.ts.map +1 -0
  105. package/dist/postgres.js +56 -0
  106. package/dist/postgres.js.map +1 -0
  107. package/dist/redis.d.ts +20 -0
  108. package/dist/redis.d.ts.map +1 -0
  109. package/dist/redis.js +83 -0
  110. package/dist/redis.js.map +1 -0
  111. package/dist/server/compat.d.ts +13 -0
  112. package/dist/server/compat.d.ts.map +1 -0
  113. package/dist/server/compat.js +5 -0
  114. package/dist/server/compat.js.map +1 -0
  115. package/dist/server/cursor.d.ts +15 -0
  116. package/dist/server/cursor.d.ts.map +1 -0
  117. package/dist/server/cursor.js +50 -0
  118. package/dist/server/cursor.js.map +1 -0
  119. package/dist/server/events.d.ts +42 -0
  120. package/dist/server/events.d.ts.map +1 -0
  121. package/dist/server/events.js +189 -0
  122. package/dist/server/events.js.map +1 -0
  123. package/dist/server/fanout.d.ts +28 -0
  124. package/dist/server/fanout.d.ts.map +1 -0
  125. package/dist/server/fanout.js +184 -0
  126. package/dist/server/fanout.js.map +1 -0
  127. package/dist/server/guard.d.ts +19 -0
  128. package/dist/server/guard.d.ts.map +1 -0
  129. package/dist/server/guard.js +27 -0
  130. package/dist/server/guard.js.map +1 -0
  131. package/dist/server/http.d.ts +4 -0
  132. package/dist/server/http.d.ts.map +1 -0
  133. package/dist/server/http.js +323 -0
  134. package/dist/server/http.js.map +1 -0
  135. package/dist/server/ingest.d.ts +4 -0
  136. package/dist/server/ingest.d.ts.map +1 -0
  137. package/dist/server/ingest.js +400 -0
  138. package/dist/server/ingest.js.map +1 -0
  139. package/dist/server/install.d.ts +5 -0
  140. package/dist/server/install.d.ts.map +1 -0
  141. package/dist/server/install.js +91 -0
  142. package/dist/server/install.js.map +1 -0
  143. package/dist/server/poll.d.ts +4 -0
  144. package/dist/server/poll.d.ts.map +1 -0
  145. package/dist/server/poll.js +45 -0
  146. package/dist/server/poll.js.map +1 -0
  147. package/dist/server/serve.d.ts +19 -0
  148. package/dist/server/serve.d.ts.map +1 -0
  149. package/dist/server/serve.js +238 -0
  150. package/dist/server/serve.js.map +1 -0
  151. package/dist/server/sessions.d.ts +14 -0
  152. package/dist/server/sessions.d.ts.map +1 -0
  153. package/dist/server/sessions.js +54 -0
  154. package/dist/server/sessions.js.map +1 -0
  155. package/dist/server/stream.d.ts +11 -0
  156. package/dist/server/stream.d.ts.map +1 -0
  157. package/dist/server/stream.js +216 -0
  158. package/dist/server/stream.js.map +1 -0
  159. package/dist/server/tools.d.ts +22 -0
  160. package/dist/server/tools.d.ts.map +1 -0
  161. package/dist/server/tools.js +55 -0
  162. package/dist/server/tools.js.map +1 -0
  163. package/dist/server/types.d.ts +351 -0
  164. package/dist/server/types.d.ts.map +1 -0
  165. package/dist/server/types.js +5 -0
  166. package/dist/server/types.js.map +1 -0
  167. package/dist/server.d.ts +11 -0
  168. package/dist/server.d.ts.map +1 -0
  169. package/dist/server.js +10 -0
  170. package/dist/server.js.map +1 -0
  171. package/dist/shell/budget.d.ts +4 -0
  172. package/dist/shell/budget.d.ts.map +1 -0
  173. package/dist/shell/budget.js +5 -0
  174. package/dist/shell/budget.js.map +1 -0
  175. package/dist/shell/copy.d.ts +20 -0
  176. package/dist/shell/copy.d.ts.map +1 -0
  177. package/dist/shell/copy.js +73 -0
  178. package/dist/shell/copy.js.map +1 -0
  179. package/dist/shell/decisions.d.ts +6 -0
  180. package/dist/shell/decisions.d.ts.map +1 -0
  181. package/dist/shell/decisions.js +42 -0
  182. package/dist/shell/decisions.js.map +1 -0
  183. package/dist/shell/read.d.ts +7 -0
  184. package/dist/shell/read.d.ts.map +1 -0
  185. package/dist/shell/read.js +21 -0
  186. package/dist/shell/read.js.map +1 -0
  187. package/dist/shell/scheduler.d.ts +4 -0
  188. package/dist/shell/scheduler.d.ts.map +1 -0
  189. package/dist/shell/scheduler.js +90 -0
  190. package/dist/shell/scheduler.js.map +1 -0
  191. package/dist/shell/scope.d.ts +27 -0
  192. package/dist/shell/scope.d.ts.map +1 -0
  193. package/dist/shell/scope.js +343 -0
  194. package/dist/shell/scope.js.map +1 -0
  195. package/dist/shell/types.d.ts +168 -0
  196. package/dist/shell/types.d.ts.map +1 -0
  197. package/dist/shell/types.js +2 -0
  198. package/dist/shell/types.js.map +1 -0
  199. package/dist/sqlite.d.ts +14 -0
  200. package/dist/sqlite.d.ts.map +1 -0
  201. package/dist/sqlite.js +39 -0
  202. package/dist/sqlite.js.map +1 -0
  203. package/dist/step.d.ts +18 -0
  204. package/dist/step.d.ts.map +1 -0
  205. package/dist/step.js +14 -0
  206. package/dist/step.js.map +1 -0
  207. package/dist/store/memory.d.ts +12 -0
  208. package/dist/store/memory.d.ts.map +1 -0
  209. package/dist/store/memory.js +264 -0
  210. package/dist/store/memory.js.map +1 -0
  211. package/dist/store/postgres.d.ts +24 -0
  212. package/dist/store/postgres.d.ts.map +1 -0
  213. package/dist/store/postgres.js +364 -0
  214. package/dist/store/postgres.js.map +1 -0
  215. package/dist/store/redis.d.ts +12 -0
  216. package/dist/store/redis.d.ts.map +1 -0
  217. package/dist/store/redis.js +540 -0
  218. package/dist/store/redis.js.map +1 -0
  219. package/dist/store/sqlite-worker.d.ts +91 -0
  220. package/dist/store/sqlite-worker.d.ts.map +1 -0
  221. package/dist/store/sqlite-worker.js +322 -0
  222. package/dist/store/sqlite-worker.js.map +1 -0
  223. package/dist/store/sqlite.d.ts +34 -0
  224. package/dist/store/sqlite.d.ts.map +1 -0
  225. package/dist/store/sqlite.js +238 -0
  226. package/dist/store/sqlite.js.map +1 -0
  227. package/dist/store/types.d.ts +137 -0
  228. package/dist/store/types.d.ts.map +1 -0
  229. package/dist/store/types.js +2 -0
  230. package/dist/store/types.js.map +1 -0
  231. package/dist/testing/conformance.d.ts +13 -0
  232. package/dist/testing/conformance.d.ts.map +1 -0
  233. package/dist/testing/conformance.js +542 -0
  234. package/dist/testing/conformance.js.map +1 -0
  235. package/dist/testing/wire.d.ts +16 -0
  236. package/dist/testing/wire.d.ts.map +1 -0
  237. package/dist/testing/wire.js +304 -0
  238. package/dist/testing/wire.js.map +1 -0
  239. package/dist/testing.d.ts +113 -0
  240. package/dist/testing.d.ts.map +1 -0
  241. package/dist/testing.js +655 -0
  242. package/dist/testing.js.map +1 -0
  243. package/dist/types.d.ts +5 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +5 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +130 -4
  248. package/skills/attend/SKILL.md +231 -0
  249. package/skills/attend/references/judges.md +283 -0
  250. package/skills/attend/references/kinds.md +62 -0
  251. package/skills/attend/references/mcp.md +132 -0
  252. package/skills/attend/references/sinks.md +73 -0
  253. package/skills/attend/references/stores.md +90 -0
  254. package/skills/attend/references/testing.md +120 -0
@@ -0,0 +1,36 @@
1
+ import type { OutboxLane } from './types.js';
2
+ /** Throw from a judge, a sink or a source to skip retries: the judge or sink dead-letters at once, and `attach` stops. */
3
+ export declare class PermanentError extends Error {
4
+ readonly permanent: true;
5
+ constructor(message: string, options?: {
6
+ cause?: unknown;
7
+ });
8
+ }
9
+ /** Duck-typed, so a PermanentError from a second copy of the package still counts. */
10
+ export declare function isPermanent(error: unknown): boolean;
11
+ /**
12
+ * `push` and a source's `emit` reject with this when a scope's outbox lane is at its cap
13
+ * (`maxOutbox` for decisions, `maxDeadLetters` for dead letters). Nothing is dropped: a sink
14
+ * or dead-letter handler that stays down eventually holds intake back until it recovers.
15
+ */
16
+ export declare class OutboxFullError extends Error {
17
+ readonly scope: string;
18
+ readonly lane: OutboxLane;
19
+ readonly size: number;
20
+ constructor(scope: string, lane: OutboxLane, size: number);
21
+ }
22
+ /**
23
+ * `push`, `end` and `flush` reject with this once the compare-and-swap budget is spent against
24
+ * other writers. Safe to retry: every input is idempotent and leases recover in-flight work.
25
+ */
26
+ export declare class ConflictError extends Error {
27
+ readonly scope: string;
28
+ constructor(scope: string, attempts: number);
29
+ }
30
+ /** Intake exceeded the queued-input or scheduler-lag limit. */
31
+ export declare class BackpressureError extends Error {
32
+ readonly retryAfterMs: number;
33
+ readonly queued: number;
34
+ constructor(retryAfterMs: number, queued: number);
35
+ }
36
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,0HAA0H;AAC1H,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,SAAS,OAAiB;IACnC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACF;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnD;AAED;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,YAAY,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAMxD;CACF;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,YAAY,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAI1C;CACF;AAED,+DAA+D;AAC/D,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,YAAY,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAK/C;CACF"}
package/dist/errors.js ADDED
@@ -0,0 +1,53 @@
1
+ /** Throw from a judge, a sink or a source to skip retries: the judge or sink dead-letters at once, and `attach` stops. */
2
+ export class PermanentError extends Error {
3
+ permanent = true;
4
+ constructor(message, options) {
5
+ super(message, options);
6
+ this.name = 'PermanentError';
7
+ }
8
+ }
9
+ /** Duck-typed, so a PermanentError from a second copy of the package still counts. */
10
+ export function isPermanent(error) {
11
+ return typeof error === 'object' && error !== null && 'permanent' in error && error.permanent === true;
12
+ }
13
+ /**
14
+ * `push` and a source's `emit` reject with this when a scope's outbox lane is at its cap
15
+ * (`maxOutbox` for decisions, `maxDeadLetters` for dead letters). Nothing is dropped: a sink
16
+ * or dead-letter handler that stays down eventually holds intake back until it recovers.
17
+ */
18
+ export class OutboxFullError extends Error {
19
+ scope;
20
+ lane;
21
+ size;
22
+ constructor(scope, lane, size) {
23
+ super(`attend: outbox for scope "${scope}" holds ${size} undelivered ${lane === 'decisions' ? 'decisions' : 'dead letters'}`);
24
+ this.name = 'OutboxFullError';
25
+ this.scope = scope;
26
+ this.lane = lane;
27
+ this.size = size;
28
+ }
29
+ }
30
+ /**
31
+ * `push`, `end` and `flush` reject with this once the compare-and-swap budget is spent against
32
+ * other writers. Safe to retry: every input is idempotent and leases recover in-flight work.
33
+ */
34
+ export class ConflictError extends Error {
35
+ scope;
36
+ constructor(scope, attempts) {
37
+ super(`attend: gave up on scope "${scope}" after ${attempts} conflicts`);
38
+ this.name = 'ConflictError';
39
+ this.scope = scope;
40
+ }
41
+ }
42
+ /** Intake exceeded the queued-input or scheduler-lag limit. */
43
+ export class BackpressureError extends Error {
44
+ retryAfterMs;
45
+ queued;
46
+ constructor(retryAfterMs, queued) {
47
+ super(`attend: over the admission limit with ${queued} inputs queued; retry in ${retryAfterMs} ms`);
48
+ this.name = 'BackpressureError';
49
+ this.retryAfterMs = retryAfterMs;
50
+ this.queued = queued;
51
+ }
52
+ }
53
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,0HAA0H;AAC1H,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,SAAS,GAAG,IAAa,CAAC;IACnC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,sFAAsF;AACtF,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;AACzG,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,KAAK,CAAS;IACd,IAAI,CAAa;IACjB,IAAI,CAAS;IACtB,YAAY,KAAa,EAAE,IAAgB,EAAE,IAAY;QACvD,KAAK,CAAC,6BAA6B,KAAK,WAAW,IAAI,gBAAgB,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QAC9H,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,KAAK,CAAS;IACvB,YAAY,KAAa,EAAE,QAAgB;QACzC,KAAK,CAAC,6BAA6B,KAAK,WAAW,QAAQ,YAAY,CAAC,CAAC;QACzE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,+DAA+D;AAC/D,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,YAAY,CAAS;IACrB,MAAM,CAAS;IACxB,YAAY,YAAoB,EAAE,MAAc;QAC9C,KAAK,CAAC,yCAAyC,MAAM,4BAA4B,YAAY,KAAK,CAAC,CAAC;QACpG,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ export { createAttend, defaultNotice, logSource, routes, BackpressureError, ConflictError, OutboxFullError, PermanentError } from './attend.js';
2
+ export type { Attend, AttendConfig, JudgeContext, RouteHandlers, RunOptions, AdmissionOptions, DeadLetterHandler, DecisionCursorPage, DecisionFilter, DecisionReadOptions } from './attend.js';
3
+ export { memoryLog, memoryStore } from './memory.js';
4
+ export { DEFAULT_POLICY, KINDS, ROUTES } from './types.js';
5
+ export type { Clock, DeadLetter, DecidedRoute, Decision, DeliveredRoute, Delivery, Entry, Event, EventLog, Judge, JudgeImage, JudgeInput, Judgment, JsonObject, JsonValue, Kind, LogEntry, OfferedRoute, Outbox, OutboxLane, Route, ScopeRecord, SettlePolicy, SettleReason, Sink, Source, SourceBatch, Trace, Verdict, Window, } from './types.js';
6
+ /** Memory-store retention options. */
7
+ export type { MemoryStoreOptions } from './memory.js';
8
+ /** Input log, judge budget, and store-port contracts for adapter authors. */
9
+ export type { JudgeBudget, Input, LoggedInput, DecisionAppend, ScopeStore, StoredScope, ScopeWrite, SerializedWrite, Snapshot, CommitOutcome, DueKey, DecisionLog, DecisionKind, DecisionRow, DecisionQuery, DecisionPage, LogBounds, Position, Retention } from './types.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChJ,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/L,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EACV,KAAK,EACL,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,KAAK,EACL,KAAK,EACL,QAAQ,EACR,KAAK,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAU,EACV,KAAK,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,EACL,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AAEpB,sCAAsC;AACtC,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,6EAA6E;AAC7E,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { createAttend, defaultNotice, logSource, routes, BackpressureError, ConflictError, OutboxFullError, PermanentError } from './attend.js';
2
+ export { memoryLog, memoryStore } from './memory.js';
3
+ export { DEFAULT_POLICY, KINDS, ROUTES } from './types.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhJ,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Checks shared by the storage adapters for what crosses their boundary: the table prefix
3
+ * going in, and rows, replies and stored JSON coming back. Every error names the adapter.
4
+ */
5
+ import type { Event, ScopeRecord } from '../types.js';
6
+ export declare function boundary(adapter: string): {
7
+ text: (value: unknown) => string;
8
+ /** The prefix is spliced into SQL as part of a table name, so it must be a bare identifier. */
9
+ tablePrefix(value?: string, options?: {
10
+ lowercase?: boolean;
11
+ }): string;
12
+ column(row: unknown, name: string): unknown;
13
+ /** Twenty digits, so positions compare as strings the way they compare as numbers. */
14
+ formatPosition(value: unknown): string;
15
+ /** The digits of a position from `formatPosition`. */
16
+ parsePosition(position: string): string;
17
+ /** The adapter wrote this JSON from a `ScopeRecord`; past the identity checks, the shape is its own. */
18
+ parseRecord(value: unknown, scope: string): ScopeRecord;
19
+ parseEvent(value: unknown): Event;
20
+ };
21
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/internal/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAItD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM;kBAIjB,OAAO,KAAG,MAAM;IAYnC,+FAA+F;0CACtD;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM;gBAQ7D,OAAO,QAAQ,MAAM,GAAG,OAAO;IAK3C,sFAAsF;0BAChE,OAAO,GAAG,MAAM;IAMtC,sDAAsD;4BAC9B,MAAM,GAAG,MAAM;IAKvC,wGAAwG;uBACrF,OAAO,SAAS,MAAM,GAAG,WAAW;sBAQrC,OAAO,GAAG,KAAK;EAUpC"}
@@ -0,0 +1,62 @@
1
+ const decoder = new TextDecoder();
2
+ export function boundary(adapter) {
3
+ const error = (message) => new Error(`${adapter}: ${message}`);
4
+ /** Drivers hand text back as a string or, like node-redis with Buffer replies, as bytes. */
5
+ const text = (value) => {
6
+ if (typeof value === 'string')
7
+ return value;
8
+ if (value instanceof Uint8Array)
9
+ return decoder.decode(value);
10
+ throw error(`expected text, got ${typeof value}`);
11
+ };
12
+ /** `pg` hands json columns back parsed; the other drivers hand back text or bytes. */
13
+ const json = (value) => (typeof value === 'string' || value instanceof Uint8Array ? JSON.parse(text(value)) : value);
14
+ return {
15
+ text,
16
+ /** The prefix is spliced into SQL as part of a table name, so it must be a bare identifier. */
17
+ tablePrefix(value = 'attend_', options) {
18
+ const [pattern, rule] = options?.lowercase
19
+ ? [/^[a-z_][a-z0-9_]*$/, 'lowercase letters, digits and underscores']
20
+ : [/^[A-Za-z_][A-Za-z0-9_]*$/, 'letters, digits and underscores'];
21
+ if (!pattern.test(value))
22
+ throw error(`prefix must be ${rule}, got "${value}"`);
23
+ return value;
24
+ },
25
+ column(row, name) {
26
+ if (typeof row !== 'object' || row === null)
27
+ throw error(`expected a row, got ${typeof row}`);
28
+ return Reflect.get(row, name);
29
+ },
30
+ /** Twenty digits, so positions compare as strings the way they compare as numbers. */
31
+ formatPosition(value) {
32
+ const digits = typeof value === 'number' || typeof value === 'bigint' ? String(value) : text(value);
33
+ if (!/^\d{1,20}$/.test(digits))
34
+ throw error(`expected an integer position, got "${digits}"`);
35
+ return digits.padStart(20, '0');
36
+ },
37
+ /** The digits of a position from `formatPosition`. */
38
+ parsePosition(position) {
39
+ if (!/^\d{1,20}$/.test(position))
40
+ throw error(`not a position from this log: "${position}"`);
41
+ return position;
42
+ },
43
+ /** The adapter wrote this JSON from a `ScopeRecord`; past the identity checks, the shape is its own. */
44
+ parseRecord(value, scope) {
45
+ const parsed = json(value);
46
+ if (typeof parsed !== 'object' || parsed === null || Reflect.get(parsed, 'scope') !== scope || typeof Reflect.get(parsed, 'version') !== 'number') {
47
+ throw error(`corrupt record for scope "${scope}"`);
48
+ }
49
+ return parsed;
50
+ },
51
+ parseEvent(value) {
52
+ const parsed = json(value);
53
+ const field = (name) => (typeof parsed === 'object' && parsed !== null ? Reflect.get(parsed, name) : undefined);
54
+ const data = field('data');
55
+ if (typeof field('id') !== 'string' || typeof field('name') !== 'string' || typeof field('at') !== 'number' || typeof data !== 'object' || data === null) {
56
+ throw error('corrupt log entry');
57
+ }
58
+ return parsed;
59
+ },
60
+ };
61
+ }
62
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/internal/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare class ConformanceError extends Error {
2
+ }
3
+ export declare function assertEqual(actual: unknown, expected: unknown, message: string): void;
4
+ export declare function assertOk(value: unknown, message: string): void;
5
+ //# sourceMappingURL=assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/internal/assert.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AAE9C,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIrF;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9D"}
@@ -0,0 +1,14 @@
1
+ import { stableJson } from './json.js';
2
+ export class ConformanceError extends Error {
3
+ }
4
+ export function assertEqual(actual, expected, message) {
5
+ const a = stableJson(actual);
6
+ const e = stableJson(expected);
7
+ if (a !== e)
8
+ throw new ConformanceError(`${message}\n expected: ${e}\n actual: ${a}`);
9
+ }
10
+ export function assertOk(value, message) {
11
+ if (!value)
12
+ throw new ConformanceError(message);
13
+ }
14
+ //# sourceMappingURL=assert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.js","sourceRoot":"","sources":["../../src/internal/assert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,OAAO,gBAAiB,SAAQ,KAAK;CAAG;AAE9C,MAAM,UAAU,WAAW,CAAC,MAAe,EAAE,QAAiB,EAAE,OAAe;IAC7E,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,gBAAgB,CAAC,GAAG,OAAO,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc,EAAE,OAAe;IACtD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Clock } from '../types.js';
2
+ /** Resolve after `ms` on `clock`, or at once on abort. */
3
+ export declare function sleep(clock: Clock, ms: number, signal: AbortSignal): Promise<void>;
4
+ /** One macrotask: every microtask chain that does not wait on real I/O has drained after it. */
5
+ export declare function drain(): Promise<void>;
6
+ /** Wall-clock timers, with already-due work scheduled on the next immediate. */
7
+ export declare function systemClock(): Clock;
8
+ //# sourceMappingURL=clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../src/internal/clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,0DAA0D;AAC1D,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlF;AAED,gGAAgG;AAChG,wBAAgB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErC;AAED,gFAAgF;AAChF,wBAAgB,WAAW,IAAI,KAAK,CAanC"}
@@ -0,0 +1,38 @@
1
+ /** Resolve after `ms` on `clock`, or at once on abort. */
2
+ export function sleep(clock, ms, signal) {
3
+ return new Promise((resolve) => {
4
+ if (signal.aborted) {
5
+ resolve();
6
+ return;
7
+ }
8
+ const onAbort = () => {
9
+ cancel();
10
+ resolve();
11
+ };
12
+ const cancel = clock.at(clock.now() + ms, () => {
13
+ signal.removeEventListener('abort', onAbort);
14
+ resolve();
15
+ });
16
+ signal.addEventListener('abort', onAbort, { once: true });
17
+ });
18
+ }
19
+ /** One macrotask: every microtask chain that does not wait on real I/O has drained after it. */
20
+ export function drain() {
21
+ return new Promise((resolve) => (typeof setImmediate === 'function' ? setImmediate(resolve) : setTimeout(resolve, 0)));
22
+ }
23
+ /** Wall-clock timers, with already-due work scheduled on the next immediate. */
24
+ export function systemClock() {
25
+ const MAX_DELAY = 2 ** 31 - 1;
26
+ return {
27
+ now: () => Date.now(),
28
+ at(at, fn) {
29
+ if (at <= Date.now()) {
30
+ const immediate = setImmediate(fn);
31
+ return () => clearImmediate(immediate);
32
+ }
33
+ const timer = setTimeout(fn, Math.min(Math.max(0, at - Date.now()), MAX_DELAY));
34
+ return () => clearTimeout(timer);
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/internal/clock.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,UAAU,KAAK,CAAC,KAAY,EAAE,EAAU,EAAE,MAAmB;IACjE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,KAAK;IACnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACzH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW;IACzB,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC9B,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,EAAE,CAAC,EAAE,EAAE,EAAE;YACP,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;gBACnC,OAAO,GAAG,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;YAChF,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ export interface Provider {
2
+ /** Prefixes every error message. */
3
+ name: string;
4
+ requestIdHeader: string;
5
+ }
6
+ /** Fields every error thrown for a non-2xx response carries, retryable or not. */
7
+ export interface ProviderFailure {
8
+ status: number;
9
+ requestId: string | null;
10
+ /** From `retry-after-ms` or `Retry-After`, when the response sent one. The core's backoff does not read it yet. */
11
+ retryAfterMs: number | null;
12
+ }
13
+ /**
14
+ * POST `body` as JSON and return the parsed reply. A network failure is a retryable Error unless
15
+ * `signal` aborted, in which case the signal's reason is thrown. A non-2xx response is classified
16
+ * by `statusError`.
17
+ */
18
+ export declare function postJson(provider: Provider, send: typeof fetch, endpoint: string, headers: Record<string, string>, body: string, signal: AbortSignal): Promise<unknown>;
19
+ /**
20
+ * Retryable (a plain Error): 408, 429 except the quota codes, and every 5xx, 529 included.
21
+ * Permanent: everything else. Both carry `ProviderFailure`.
22
+ */
23
+ export declare function statusError(provider: Provider, res: Response, text: string): Error & ProviderFailure;
24
+ /** True for an error from `statusError` whose status is one a provider uses to reject an image. */
25
+ export declare function isImageRejection(error: unknown): boolean;
26
+ /**
27
+ * True for a 400 or 413 that names the model's context length: in the response text, for an error
28
+ * from `statusError`, or in the `code` or `message` of any other error, such as a vendor SDK's.
29
+ */
30
+ export declare function isContextLengthRejection(error: unknown): boolean;
31
+ /**
32
+ * The provider's own description, from any of the documented body shapes: `error` as a string or
33
+ * `{ message, code, type }`, `message`, or `detail` as a string, `{ message }` or `[{ msg, loc }]`.
34
+ * Anything else falls back to the raw text, truncated.
35
+ */
36
+ export declare function parseErrorBody(text: string): {
37
+ message: string;
38
+ code: string | null;
39
+ };
40
+ /** `retry-after-ms` first, then `Retry-After` as seconds or an HTTP date; null when absent or unreadable. */
41
+ export declare function retryAfterMs(headers: Headers, now?: number): number | null;
42
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,QAAQ;IACvB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mHAAmH;IACnH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAcD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB7K;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,eAAe,CAUpG;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIhE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAuBrF;AAED,6GAA6G;AAC7G,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI,CAQ9E"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * What the hosted judges share at the HTTP boundary: one POST, one table from status to
3
+ * retryable or permanent, the provider's error body parsed defensively, and the request id and
4
+ * `Retry-After` carried on the thrown error.
5
+ */
6
+ import { PermanentError } from '../errors.js';
7
+ import { isRecord } from './shared.js';
8
+ /** 429 codes that a retry never clears: billing and quota, which openai-node would retry anyway. */
9
+ const QUOTA_CODES = new Set(['credit_balance_exhausted', 'organization_spend_limit_exceeded', 'project_spend_limit_exceeded', 'organization_usage_limit_exceeded', 'insufficient_quota']);
10
+ /** How OpenAI (including the Decisions API's "exceeds the token limit"), Anthropic, Gemini, TypeSafe and OpenRouter word a request too long for the model. */
11
+ const CONTEXT_LENGTH = /context[ _-]?(length|window)|max_tokens_exceeded|prompt is too long|input token count|too many (input )?tokens|token limit/i;
12
+ // TypeSafe names its code without saying which body field carries it, so the raw text is checked when the error is made.
13
+ const statusFailures = new WeakSet();
14
+ const contextLengthFailures = new WeakSet();
15
+ /** Statuses a provider returns when it rejects an image, when the request carried any. */
16
+ const IMAGE_REJECTIONS = new Set([400, 413, 415, 422]);
17
+ /**
18
+ * POST `body` as JSON and return the parsed reply. A network failure is a retryable Error unless
19
+ * `signal` aborted, in which case the signal's reason is thrown. A non-2xx response is classified
20
+ * by `statusError`.
21
+ */
22
+ export async function postJson(provider, send, endpoint, headers, body, signal) {
23
+ // The judge renders the window across awaits before this, so the call may already be aborted.
24
+ signal.throwIfAborted();
25
+ let res;
26
+ try {
27
+ res = await send(endpoint, { method: 'POST', body, headers: { 'content-type': 'application/json', ...headers }, signal });
28
+ }
29
+ catch (error) {
30
+ signal.throwIfAborted();
31
+ throw new Error(`${provider.name}: request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
32
+ }
33
+ if (!res.ok)
34
+ throw statusError(provider, res, await res.text().catch(() => ''));
35
+ try {
36
+ return await res.json();
37
+ }
38
+ catch (error) {
39
+ throw new Error(`${provider.name}: response is not JSON`, { cause: error });
40
+ }
41
+ }
42
+ /**
43
+ * Retryable (a plain Error): 408, 429 except the quota codes, and every 5xx, 529 included.
44
+ * Permanent: everything else. Both carry `ProviderFailure`.
45
+ */
46
+ export function statusError(provider, res, text) {
47
+ const { message, code } = parseErrorBody(text);
48
+ const requestId = res.headers.get(provider.requestIdHeader);
49
+ const retryable = res.status === 408 || res.status >= 500 || (res.status === 429 && !QUOTA_CODES.has(code ?? ''));
50
+ const described = `${provider.name}: HTTP ${res.status}${message === '' ? '' : `: ${message}`}${requestId === null ? '' : ` (request ${requestId})`}`;
51
+ const failure = { status: res.status, requestId, retryAfterMs: retryAfterMs(res.headers) };
52
+ const error = Object.assign(retryable ? new Error(described) : new PermanentError(described), failure);
53
+ statusFailures.add(error);
54
+ if ((res.status === 400 || res.status === 413) && CONTEXT_LENGTH.test(text))
55
+ contextLengthFailures.add(error);
56
+ return error;
57
+ }
58
+ /** True for an error from `statusError` whose status is one a provider uses to reject an image. */
59
+ export function isImageRejection(error) {
60
+ return error instanceof Error && 'status' in error && typeof error.status === 'number' && IMAGE_REJECTIONS.has(error.status);
61
+ }
62
+ /**
63
+ * True for a 400 or 413 that names the model's context length: in the response text, for an error
64
+ * from `statusError`, or in the `code` or `message` of any other error, such as a vendor SDK's.
65
+ */
66
+ export function isContextLengthRejection(error) {
67
+ if (!(error instanceof Error) || !('status' in error) || (error.status !== 400 && error.status !== 413))
68
+ return false;
69
+ if (statusFailures.has(error))
70
+ return contextLengthFailures.has(error);
71
+ return CONTEXT_LENGTH.test(error.message) || ('code' in error && typeof error.code === 'string' && CONTEXT_LENGTH.test(error.code));
72
+ }
73
+ /**
74
+ * The provider's own description, from any of the documented body shapes: `error` as a string or
75
+ * `{ message, code, type }`, `message`, or `detail` as a string, `{ message }` or `[{ msg, loc }]`.
76
+ * Anything else falls back to the raw text, truncated.
77
+ */
78
+ export function parseErrorBody(text) {
79
+ let body;
80
+ try {
81
+ body = JSON.parse(text);
82
+ }
83
+ catch {
84
+ return { message: text.slice(0, 500), code: null };
85
+ }
86
+ if (!isRecord(body))
87
+ return { message: text.slice(0, 500), code: null };
88
+ const error = body.error;
89
+ if (typeof error === 'string')
90
+ return { message: error, code: null };
91
+ if (isRecord(error)) {
92
+ const code = typeof error.code === 'string' ? error.code : typeof error.type === 'string' ? error.type : null;
93
+ return { message: typeof error.message === 'string' ? error.message : text.slice(0, 500), code };
94
+ }
95
+ if (typeof body.message === 'string')
96
+ return { message: body.message, code: null };
97
+ const detail = body.detail;
98
+ if (typeof detail === 'string')
99
+ return { message: detail, code: null };
100
+ if (isRecord(detail) && typeof detail.message === 'string')
101
+ return { message: detail.message, code: null };
102
+ if (Array.isArray(detail)) {
103
+ const lines = detail.filter(isRecord).map((d) => `${Array.isArray(d.loc) ? `${d.loc.join('.')}: ` : ''}${typeof d.msg === 'string' ? d.msg : JSON.stringify(d)}`);
104
+ if (lines.length > 0)
105
+ return { message: lines.join('; '), code: null };
106
+ }
107
+ return { message: text.slice(0, 500), code: null };
108
+ }
109
+ /** `retry-after-ms` first, then `Retry-After` as seconds or an HTTP date; null when absent or unreadable. */
110
+ export function retryAfterMs(headers, now = Date.now()) {
111
+ const ms = headers.get('retry-after-ms');
112
+ if (ms !== null && /^\d+$/.test(ms.trim()))
113
+ return Number(ms);
114
+ const after = headers.get('retry-after');
115
+ if (after === null)
116
+ return null;
117
+ if (/^\d+$/.test(after.trim()))
118
+ return Number(after) * 1000;
119
+ const at = Date.parse(after);
120
+ return Number.isNaN(at) ? null : Math.max(0, at - now);
121
+ }
122
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Image checks for a judge that rejects a whole request over one bad image. Reads only the
3
+ * PNG IHDR or JPEG SOF header, decoding base64 three bytes at a time, so a 16 MiB file costs a
4
+ * few dozen decodes rather than one copy.
5
+ */
6
+ export interface ImageHeader {
7
+ format: 'png' | 'jpeg';
8
+ width: number;
9
+ height: number;
10
+ animated: boolean;
11
+ }
12
+ /** True for the standard alphabet with `=` padding and no whitespace, which is what the providers accept. */
13
+ export declare function isStandardBase64(data: string): boolean;
14
+ /** The byte count a base64 string decodes to, without decoding it. */
15
+ export declare function decodedLength(data: string): number;
16
+ /** Width, height and format from the header of a base64 PNG or JPEG; null when it is neither or the header is cut short. */
17
+ export declare function imageHeader(data: string): ImageHeader | null;
18
+ //# sourceMappingURL=images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/internal/images.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,6GAA6G;AAC7G,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,4HAA4H;AAC5H,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAsD5D"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Image checks for a judge that rejects a whole request over one bad image. Reads only the
3
+ * PNG IHDR or JPEG SOF header, decoding base64 three bytes at a time, so a 16 MiB file costs a
4
+ * few dozen decodes rather than one copy.
5
+ */
6
+ // No repeated group: V8 recurses per repetition and overflows the stack on a 20 MB image.
7
+ const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
8
+ /** True for the standard alphabet with `=` padding and no whitespace, which is what the providers accept. */
9
+ export function isStandardBase64(data) {
10
+ return data.length > 0 && data.length % 4 === 0 && BASE64.test(data);
11
+ }
12
+ /** The byte count a base64 string decodes to, without decoding it. */
13
+ export function decodedLength(data) {
14
+ const padding = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0;
15
+ return (data.length / 4) * 3 - padding;
16
+ }
17
+ /** Width, height and format from the header of a base64 PNG or JPEG; null when it is neither or the header is cut short. */
18
+ export function imageHeader(data) {
19
+ const at = (i) => {
20
+ const group = Math.floor(i / 3);
21
+ const decoded = atob(data.slice(group * 4, group * 4 + 4));
22
+ const code = decoded.charCodeAt(i - group * 3);
23
+ return Number.isNaN(code) ? null : code;
24
+ };
25
+ const u16 = (i) => {
26
+ const [a, b] = [at(i), at(i + 1)];
27
+ return a === null || b === null ? null : (a << 8) | b;
28
+ };
29
+ const u32 = (i) => {
30
+ const [a, b] = [u16(i), u16(i + 2)];
31
+ return a === null || b === null ? null : a * 65_536 + b;
32
+ };
33
+ const tag = (i) => {
34
+ const bytes = [at(i), at(i + 1), at(i + 2), at(i + 3)];
35
+ return bytes.some((b) => b === null) ? null : String.fromCharCode(...bytes.map((b) => b ?? 0));
36
+ };
37
+ if (u32(0) === 0x89504e47 && u32(4) === 0x0d0a1a0a && tag(12) === 'IHDR') {
38
+ const [width, height] = [u32(16), u32(20)];
39
+ if (width === null || height === null)
40
+ return null;
41
+ let animated = false;
42
+ for (let offset = 8;;) {
43
+ const [length, type] = [u32(offset), tag(offset + 4)];
44
+ if (length === null || type === null || type === 'IDAT' || type === 'IEND')
45
+ break;
46
+ if (type === 'acTL')
47
+ animated = true;
48
+ offset += 12 + length;
49
+ }
50
+ return { format: 'png', width, height, animated };
51
+ }
52
+ if (u16(0) === 0xffd8) {
53
+ for (let offset = 2;;) {
54
+ const [marker, code] = [at(offset), at(offset + 1)];
55
+ if (marker !== 0xff || code === null)
56
+ return null;
57
+ if (code === 0xff) {
58
+ offset += 1;
59
+ continue;
60
+ }
61
+ const standalone = code === 0x01 || (code >= 0xd0 && code <= 0xd9);
62
+ const frame = code >= 0xc0 && code <= 0xcf && code !== 0xc4 && code !== 0xc8 && code !== 0xcc;
63
+ if (frame) {
64
+ const [height, width] = [u16(offset + 5), u16(offset + 7)];
65
+ return height === null || width === null ? null : { format: 'jpeg', width, height, animated: false };
66
+ }
67
+ const length = standalone ? 0 : u16(offset + 2);
68
+ if (length === null)
69
+ return null;
70
+ offset += 2 + length;
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ //# sourceMappingURL=images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.js","sourceRoot":"","sources":["../../src/internal/images.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** JSON with every object's keys sorted, so equal values give equal text. */
2
+ export declare function stableJson(value: unknown): string;
3
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/internal/json.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIjD"}
@@ -0,0 +1,5 @@
1
+ /** JSON with every object's keys sorted, so equal values give equal text. */
2
+ export function stableJson(value) {
3
+ return JSON.stringify(value, (_key, v) => typeof v === 'object' && v !== null && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) : v);
4
+ }
5
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/internal/json.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAU,EAAE,EAAE,CAChD,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACtJ,CAAC;AACJ,CAAC"}