@prenta/core 8.9.2 → 8.10.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 (290) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/dist/actions.d.ts +25 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +51 -4
  5. package/dist/actions.js.map +1 -1
  6. package/dist/ai/batch-links.d.ts +105 -0
  7. package/dist/ai/batch-links.d.ts.map +1 -0
  8. package/dist/ai/batch-links.js +667 -0
  9. package/dist/ai/batch-links.js.map +1 -0
  10. package/dist/ai/batch-list.d.ts +127 -4
  11. package/dist/ai/batch-list.d.ts.map +1 -1
  12. package/dist/ai/batch-list.js +250 -14
  13. package/dist/ai/batch-list.js.map +1 -1
  14. package/dist/ai/providers/http.d.ts +4 -0
  15. package/dist/ai/providers/http.d.ts.map +1 -1
  16. package/dist/ai/providers/http.js +9 -8
  17. package/dist/ai/providers/http.js.map +1 -1
  18. package/dist/ai/tasks/editor-text.d.ts +39 -0
  19. package/dist/ai/tasks/editor-text.d.ts.map +1 -0
  20. package/dist/ai/tasks/editor-text.js +45 -0
  21. package/dist/ai/tasks/editor-text.js.map +1 -0
  22. package/dist/ai/tasks/link-embeddings.d.ts +22 -0
  23. package/dist/ai/tasks/link-embeddings.d.ts.map +1 -1
  24. package/dist/ai/tasks/link-embeddings.js +24 -10
  25. package/dist/ai/tasks/link-embeddings.js.map +1 -1
  26. package/dist/ai/usage.d.ts +7 -0
  27. package/dist/ai/usage.d.ts.map +1 -1
  28. package/dist/ai/usage.js +11 -0
  29. package/dist/ai/usage.js.map +1 -1
  30. package/dist/api/guarded-db.d.ts +6 -0
  31. package/dist/api/guarded-db.d.ts.map +1 -1
  32. package/dist/api/guarded-db.js +13 -1
  33. package/dist/api/guarded-db.js.map +1 -1
  34. package/dist/api/handlers.d.ts.map +1 -1
  35. package/dist/api/handlers.js +2 -0
  36. package/dist/api/handlers.js.map +1 -1
  37. package/dist/api/openapi.d.ts.map +1 -1
  38. package/dist/api/openapi.js +47 -0
  39. package/dist/api/openapi.js.map +1 -1
  40. package/dist/api/route-helpers/forms.d.ts.map +1 -1
  41. package/dist/api/route-helpers/forms.js +7 -1
  42. package/dist/api/route-helpers/forms.js.map +1 -1
  43. package/dist/api/routes/ai-authoring.d.ts.map +1 -1
  44. package/dist/api/routes/ai-authoring.js +1 -0
  45. package/dist/api/routes/ai-authoring.js.map +1 -1
  46. package/dist/api/routes/ai-seo.d.ts.map +1 -1
  47. package/dist/api/routes/ai-seo.js +20 -18
  48. package/dist/api/routes/ai-seo.js.map +1 -1
  49. package/dist/api/routes/media.d.ts.map +1 -1
  50. package/dist/api/routes/media.js +3 -1
  51. package/dist/api/routes/media.js.map +1 -1
  52. package/dist/api/routes/scheduling.d.ts.map +1 -1
  53. package/dist/api/routes/scheduling.js +33 -2
  54. package/dist/api/routes/scheduling.js.map +1 -1
  55. package/dist/appearance/color.d.ts +17 -0
  56. package/dist/appearance/color.d.ts.map +1 -1
  57. package/dist/appearance/color.js +162 -1
  58. package/dist/appearance/color.js.map +1 -1
  59. package/dist/appearance/index.d.ts +3 -3
  60. package/dist/appearance/index.d.ts.map +1 -1
  61. package/dist/appearance/index.js +2 -2
  62. package/dist/appearance/index.js.map +1 -1
  63. package/dist/appearance/resolve.d.ts.map +1 -1
  64. package/dist/appearance/resolve.js +4 -2
  65. package/dist/appearance/resolve.js.map +1 -1
  66. package/dist/appearance/theme-tokens.d.ts +60 -11
  67. package/dist/appearance/theme-tokens.d.ts.map +1 -1
  68. package/dist/appearance/theme-tokens.js +184 -175
  69. package/dist/appearance/theme-tokens.js.map +1 -1
  70. package/dist/appearance/types.d.ts +16 -2
  71. package/dist/appearance/types.d.ts.map +1 -1
  72. package/dist/astro-site.d.ts +1 -11
  73. package/dist/astro-site.d.ts.map +1 -1
  74. package/dist/astro-site.js +4 -0
  75. package/dist/astro-site.js.map +1 -1
  76. package/dist/auth/team.d.ts +1 -0
  77. package/dist/auth/team.d.ts.map +1 -1
  78. package/dist/auth/team.js +1 -1
  79. package/dist/auth/team.js.map +1 -1
  80. package/dist/cache/http.d.ts +20 -0
  81. package/dist/cache/http.d.ts.map +1 -1
  82. package/dist/cache/http.js +42 -0
  83. package/dist/cache/http.js.map +1 -1
  84. package/dist/chrome/announcement.d.ts +30 -0
  85. package/dist/chrome/announcement.d.ts.map +1 -0
  86. package/dist/chrome/announcement.js +190 -0
  87. package/dist/chrome/announcement.js.map +1 -0
  88. package/dist/chrome/codegen.d.ts +17 -0
  89. package/dist/chrome/codegen.d.ts.map +1 -0
  90. package/dist/chrome/codegen.js +96 -0
  91. package/dist/chrome/codegen.js.map +1 -0
  92. package/dist/chrome/contract.d.ts +142 -0
  93. package/dist/chrome/contract.d.ts.map +1 -0
  94. package/dist/chrome/contract.js +2 -0
  95. package/dist/chrome/contract.js.map +1 -0
  96. package/dist/chrome/memory-store.d.ts +15 -0
  97. package/dist/chrome/memory-store.d.ts.map +1 -0
  98. package/dist/chrome/memory-store.js +54 -0
  99. package/dist/chrome/memory-store.js.map +1 -0
  100. package/dist/chrome/parse.d.ts +36 -0
  101. package/dist/chrome/parse.d.ts.map +1 -0
  102. package/dist/chrome/parse.js +277 -0
  103. package/dist/chrome/parse.js.map +1 -0
  104. package/dist/chrome/prisma-store.d.ts +11 -0
  105. package/dist/chrome/prisma-store.d.ts.map +1 -0
  106. package/dist/chrome/prisma-store.js +48 -0
  107. package/dist/chrome/prisma-store.js.map +1 -0
  108. package/dist/chrome/public.d.ts +22 -0
  109. package/dist/chrome/public.d.ts.map +1 -0
  110. package/dist/chrome/public.js +181 -0
  111. package/dist/chrome/public.js.map +1 -0
  112. package/dist/chrome/resolve.d.ts +36 -0
  113. package/dist/chrome/resolve.d.ts.map +1 -0
  114. package/dist/chrome/resolve.js +165 -0
  115. package/dist/chrome/resolve.js.map +1 -0
  116. package/dist/chrome/revalidate.d.ts +9 -0
  117. package/dist/chrome/revalidate.d.ts.map +1 -0
  118. package/dist/chrome/revalidate.js +51 -0
  119. package/dist/chrome/revalidate.js.map +1 -0
  120. package/dist/chrome/routes.d.ts +14 -0
  121. package/dist/chrome/routes.d.ts.map +1 -0
  122. package/dist/chrome/routes.js +306 -0
  123. package/dist/chrome/routes.js.map +1 -0
  124. package/dist/chrome/schema.d.ts +231 -0
  125. package/dist/chrome/schema.d.ts.map +1 -0
  126. package/dist/chrome/schema.js +73 -0
  127. package/dist/chrome/schema.js.map +1 -0
  128. package/dist/chrome/service.d.ts +76 -0
  129. package/dist/chrome/service.d.ts.map +1 -0
  130. package/dist/chrome/service.js +286 -0
  131. package/dist/chrome/service.js.map +1 -0
  132. package/dist/chrome/settings.d.ts +14 -0
  133. package/dist/chrome/settings.d.ts.map +1 -0
  134. package/dist/chrome/settings.js +142 -0
  135. package/dist/chrome/settings.js.map +1 -0
  136. package/dist/chrome/store.d.ts +48 -0
  137. package/dist/chrome/store.d.ts.map +1 -0
  138. package/dist/chrome/store.js +26 -0
  139. package/dist/chrome/store.js.map +1 -0
  140. package/dist/chrome/values.d.ts +98 -0
  141. package/dist/chrome/values.d.ts.map +1 -0
  142. package/dist/chrome/values.js +491 -0
  143. package/dist/chrome/values.js.map +1 -0
  144. package/dist/config/define.d.ts +2 -0
  145. package/dist/config/define.d.ts.map +1 -1
  146. package/dist/config/define.js +2 -0
  147. package/dist/config/define.js.map +1 -1
  148. package/dist/db/model-types.d.ts +62 -0
  149. package/dist/db/model-types.d.ts.map +1 -1
  150. package/dist/forms/attribution-settings.d.ts +23 -0
  151. package/dist/forms/attribution-settings.d.ts.map +1 -0
  152. package/dist/forms/attribution-settings.js +42 -0
  153. package/dist/forms/attribution-settings.js.map +1 -0
  154. package/dist/forms/attribution.d.ts +5 -1
  155. package/dist/forms/attribution.d.ts.map +1 -1
  156. package/dist/forms/attribution.js +6 -4
  157. package/dist/forms/attribution.js.map +1 -1
  158. package/dist/forms/client-validation.d.ts.map +1 -1
  159. package/dist/forms/client-validation.js +3 -0
  160. package/dist/forms/client-validation.js.map +1 -1
  161. package/dist/forms/form-model.d.ts +109 -0
  162. package/dist/forms/form-model.d.ts.map +1 -0
  163. package/dist/forms/form-model.js +192 -0
  164. package/dist/forms/form-model.js.map +1 -0
  165. package/dist/forms/index.d.ts +2 -2
  166. package/dist/forms/index.d.ts.map +1 -1
  167. package/dist/forms/index.js +1 -1
  168. package/dist/forms/index.js.map +1 -1
  169. package/dist/forms/service.d.ts +19 -1
  170. package/dist/forms/service.d.ts.map +1 -1
  171. package/dist/forms/service.js +152 -0
  172. package/dist/forms/service.js.map +1 -1
  173. package/dist/forms/spam.d.ts +0 -12
  174. package/dist/forms/spam.d.ts.map +1 -1
  175. package/dist/forms/spam.js +30 -0
  176. package/dist/forms/spam.js.map +1 -1
  177. package/dist/forms/submission.d.ts +7 -0
  178. package/dist/forms/submission.d.ts.map +1 -1
  179. package/dist/forms/submission.js +33 -0
  180. package/dist/forms/submission.js.map +1 -1
  181. package/dist/forms/types.d.ts +26 -1
  182. package/dist/forms/types.d.ts.map +1 -1
  183. package/dist/forms/types.js +9 -1
  184. package/dist/forms/types.js.map +1 -1
  185. package/dist/generated/browser.d.ts +35 -3
  186. package/dist/generated/client.d.ts +35 -3
  187. package/dist/generated/internal/class.d.ts +44 -0
  188. package/dist/generated/internal/class.js +4 -4
  189. package/dist/generated/internal/prismaNamespace.d.ts +403 -1
  190. package/dist/generated/internal/prismaNamespace.js +95 -1
  191. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +102 -0
  192. package/dist/generated/internal/prismaNamespaceBrowser.js +95 -1
  193. package/dist/generated/models/ChromeRegion.d.ts +1203 -0
  194. package/dist/generated/models/ChromeRegion.js +1 -0
  195. package/dist/generated/models/Job.d.ts +732 -5
  196. package/dist/generated/models/JobEvent.d.ts +1339 -0
  197. package/dist/generated/models/JobEvent.js +1 -0
  198. package/dist/generated/models/JobReviewItem.d.ts +1470 -0
  199. package/dist/generated/models/JobReviewItem.js +1 -0
  200. package/dist/generated/models/SystemSetting.d.ts +952 -0
  201. package/dist/generated/models/SystemSetting.js +1 -0
  202. package/dist/generated/models.d.ts +4 -0
  203. package/dist/index.d.ts +12 -5
  204. package/dist/index.d.ts.map +1 -1
  205. package/dist/index.js +8 -3
  206. package/dist/index.js.map +1 -1
  207. package/dist/jobs/batch-ai.d.ts +53 -0
  208. package/dist/jobs/batch-ai.d.ts.map +1 -0
  209. package/dist/jobs/batch-ai.js +314 -0
  210. package/dist/jobs/batch-ai.js.map +1 -0
  211. package/dist/jobs/contract.d.ts +186 -0
  212. package/dist/jobs/contract.d.ts.map +1 -0
  213. package/dist/jobs/contract.js +2 -0
  214. package/dist/jobs/contract.js.map +1 -0
  215. package/dist/jobs/error-text.d.ts +23 -0
  216. package/dist/jobs/error-text.d.ts.map +1 -0
  217. package/dist/jobs/error-text.js +110 -0
  218. package/dist/jobs/error-text.js.map +1 -0
  219. package/dist/jobs/handlers.d.ts.map +1 -1
  220. package/dist/jobs/handlers.js +48 -7
  221. package/dist/jobs/handlers.js.map +1 -1
  222. package/dist/jobs/memory-store.d.ts +26 -2
  223. package/dist/jobs/memory-store.d.ts.map +1 -1
  224. package/dist/jobs/memory-store.js +157 -3
  225. package/dist/jobs/memory-store.js.map +1 -1
  226. package/dist/jobs/outcomes.d.ts +46 -0
  227. package/dist/jobs/outcomes.d.ts.map +1 -0
  228. package/dist/jobs/outcomes.js +251 -0
  229. package/dist/jobs/outcomes.js.map +1 -0
  230. package/dist/jobs/prisma-store.d.ts +14 -2
  231. package/dist/jobs/prisma-store.d.ts.map +1 -1
  232. package/dist/jobs/prisma-store.js +257 -15
  233. package/dist/jobs/prisma-store.js.map +1 -1
  234. package/dist/jobs/queue.d.ts +62 -2
  235. package/dist/jobs/queue.d.ts.map +1 -1
  236. package/dist/jobs/queue.js +412 -36
  237. package/dist/jobs/queue.js.map +1 -1
  238. package/dist/jobs/retention.d.ts +11 -0
  239. package/dist/jobs/retention.d.ts.map +1 -0
  240. package/dist/jobs/retention.js +18 -0
  241. package/dist/jobs/retention.js.map +1 -0
  242. package/dist/jobs/review.d.ts +111 -0
  243. package/dist/jobs/review.d.ts.map +1 -0
  244. package/dist/jobs/review.js +461 -0
  245. package/dist/jobs/review.js.map +1 -0
  246. package/dist/jobs/routes.d.ts.map +1 -1
  247. package/dist/jobs/routes.js +491 -16
  248. package/dist/jobs/routes.js.map +1 -1
  249. package/dist/jobs/serialize.d.ts +40 -0
  250. package/dist/jobs/serialize.d.ts.map +1 -0
  251. package/dist/jobs/serialize.js +270 -0
  252. package/dist/jobs/serialize.js.map +1 -0
  253. package/dist/jobs/types.d.ts +141 -2
  254. package/dist/jobs/types.d.ts.map +1 -1
  255. package/dist/jobs/worker-status.d.ts +27 -0
  256. package/dist/jobs/worker-status.d.ts.map +1 -0
  257. package/dist/jobs/worker-status.js +66 -0
  258. package/dist/jobs/worker-status.js.map +1 -0
  259. package/dist/media/optimize.d.ts.map +1 -1
  260. package/dist/media/optimize.js +4 -2
  261. package/dist/media/optimize.js.map +1 -1
  262. package/dist/next-site.d.ts +1 -0
  263. package/dist/next-site.d.ts.map +1 -1
  264. package/dist/next-site.js +3 -0
  265. package/dist/next-site.js.map +1 -1
  266. package/dist/seo/audit-runner.d.ts.map +1 -1
  267. package/dist/seo/audit-runner.js +23 -2
  268. package/dist/seo/audit-runner.js.map +1 -1
  269. package/dist/seo/issue-fix-link-insert.d.ts +11 -0
  270. package/dist/seo/issue-fix-link-insert.d.ts.map +1 -1
  271. package/dist/seo/issue-fix-link-insert.js +122 -8
  272. package/dist/seo/issue-fix-link-insert.js.map +1 -1
  273. package/dist/server-site.d.ts.map +1 -1
  274. package/dist/server-site.js +15 -0
  275. package/dist/server-site.js.map +1 -1
  276. package/dist/site.d.ts +8 -0
  277. package/dist/site.d.ts.map +1 -1
  278. package/dist/site.js +6 -0
  279. package/dist/site.js.map +1 -1
  280. package/dist/webhooks/index.d.ts +3 -1
  281. package/dist/webhooks/index.d.ts.map +1 -1
  282. package/dist/webhooks/index.js.map +1 -1
  283. package/package.json +6 -1
  284. package/prisma/migrations/0025_job_cancel_review/down.sql +60 -0
  285. package/prisma/migrations/0025_job_cancel_review/migration.sql +56 -0
  286. package/prisma/migrations/0026_job_creator_system_settings/down.sql +30 -0
  287. package/prisma/migrations/0026_job_creator_system_settings/migration.sql +14 -0
  288. package/prisma/migrations/0027_chrome_regions/down.sql +24 -0
  289. package/prisma/migrations/0027_chrome_regions/migration.sql +16 -0
  290. package/prisma/schema.prisma +105 -15
@@ -1,9 +1,36 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { clipError, describeError } from './error-text.js';
2
3
  const BACKOFF_BASE_MS = 30_000;
3
4
  const BACKOFF_CAP_MS = 15 * 60_000;
4
5
  const DEFAULT_MAX_ATTEMPTS = 3;
5
6
  const DEFAULT_BUDGET_MS = 20_000;
6
7
  const DEFAULT_STALE_LOCK_MS = 10 * 60_000;
8
+ /** An AI note call never takes longer than this. */
9
+ const NOTE_TIMEOUT_MS = 8000;
10
+ /** No AI note call starts with less time than this left before its deadline. */
11
+ const NOTE_MIN_MS = 2000;
12
+ /** Kept back from a note call's deadline for the write that follows it. */
13
+ const NOTE_WRITE_MS = 500;
14
+ /** Notes before the main loop may use this share of the budget. */
15
+ const NOTE_LEAD_SHARE = 0.5;
16
+ /** Jobs that finished longer ago than this get no AI note. */
17
+ const NOTE_WINDOW_MS = 24 * 60 * 60_000;
18
+ /** Pending notes read per pass. */
19
+ const NOTE_BATCH = 10;
20
+ /** Retention: finished jobs are deleted this long after they finish, with their events. */
21
+ const RETENTION_MS = 30 * 24 * 60 * 60_000;
22
+ /**
23
+ * What one tick's retention deletes at most: 50 jobs, and 5,000 events and
24
+ * review items with them past the first job, so the cascade stays a short
25
+ * statement even for jobs whose logs predate the cap below.
26
+ */
27
+ const PRUNE_LIMIT = { jobs: 50, rows: 5000 };
28
+ /** Retention runs only with this much of the budget left after the slices. */
29
+ const PRUNE_MIN_MS = 2000;
30
+ /** Events a job keeps once it ends. The admin shows the newest 50. */
31
+ const EVENTS_KEPT = 100;
32
+ /** Each batch AI job is its own set of documents, so one is never reused for another. */
33
+ const NEVER_REUSED = new Set(['batch-ai']);
7
34
  function emptyProgress() {
8
35
  return { completed: 0, total: 0 };
9
36
  }
@@ -11,13 +38,70 @@ function backoffMs(attempts) {
11
38
  const exp = Math.min(Math.max(attempts - 1, 0), 8);
12
39
  return Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** exp);
13
40
  }
14
- export async function enqueueJob(store, input) {
15
- const now = input.now ?? new Date();
16
- if (input.dedupe !== false) {
17
- const active = await store.findActive(input.type);
18
- if (active)
19
- return active;
41
+ function formatWait(ms) {
42
+ if (ms < 60_000)
43
+ return `${Math.round(ms / 1000)}s`;
44
+ const minutes = Math.floor(ms / 60_000);
45
+ const seconds = Math.round((ms % 60_000) / 1000);
46
+ return seconds ? `${minutes}m ${seconds}s` : `${minutes}m`;
47
+ }
48
+ /** The activity log is best-effort: a failed write never blocks a status transition. */
49
+ async function recordEvent(store, event) {
50
+ try {
51
+ await store.addEvent(event);
52
+ }
53
+ catch {
54
+ // The job row is the source of truth. The log only explains how it got there.
55
+ }
56
+ }
57
+ /**
58
+ * After a job's last event, keeps only its newest {@link EVENTS_KEPT}, so a job
59
+ * that ran many slices doesn't keep hundreds of rows nobody sees. Best-effort,
60
+ * like the log.
61
+ */
62
+ async function trimLog(store, jobId) {
63
+ try {
64
+ await store.trimEvents(jobId, EVENTS_KEPT);
65
+ }
66
+ catch {
67
+ // A longer log only costs rows. Retention removes it with the job.
20
68
  }
69
+ }
70
+ /**
71
+ * Retention, at most once per tick and only in time the slices left: deletes
72
+ * one batch of jobs that finished more than {@link RETENTION_MS} ago, with
73
+ * their events. A tick that skips it or fails leaves the rest for the next.
74
+ */
75
+ async function pruneOldJobs(store, started, deadline, clock) {
76
+ if (deadline.getTime() - clock().getTime() < PRUNE_MIN_MS)
77
+ return;
78
+ try {
79
+ await store.pruneFinished(new Date(started.getTime() - RETENTION_MS), PRUNE_LIMIT);
80
+ }
81
+ catch {
82
+ // Old rows wait for the next tick.
83
+ }
84
+ }
85
+ function addUsage(job, usage) {
86
+ if (!usage)
87
+ return job;
88
+ return {
89
+ ...job,
90
+ tokensIn: (job.tokensIn ?? 0) + usage.tokensIn,
91
+ tokensOut: (job.tokensOut ?? 0) + usage.tokensOut,
92
+ };
93
+ }
94
+ function usageTokens(usage) {
95
+ return usage ? usage.tokensIn + usage.tokensOut : null;
96
+ }
97
+ /** The queued or running job a new request of this type should reuse, if any. */
98
+ async function findReusable(store, type, dedupe = true) {
99
+ if (!dedupe || NEVER_REUSED.has(type))
100
+ return null;
101
+ return store.findActive(type);
102
+ }
103
+ async function insertJob(store, input) {
104
+ const now = input.now ?? new Date();
21
105
  const job = {
22
106
  id: randomUUID(),
23
107
  type: input.type,
@@ -29,35 +113,183 @@ export async function enqueueJob(store, input) {
29
113
  lockedAt: null,
30
114
  lastError: null,
31
115
  progress: emptyProgress(),
116
+ createdById: input.createdById ?? null,
117
+ title: input.title ?? null,
118
+ scope: input.scope ?? null,
32
119
  createdAt: now,
33
120
  updatedAt: now,
34
121
  };
35
122
  await store.insert(job);
123
+ await recordEvent(store, {
124
+ jobId: job.id,
125
+ at: now,
126
+ kind: 'queued',
127
+ message: job.createdById ? 'Queued' : 'Queued by the scheduler',
128
+ });
36
129
  return job;
37
130
  }
131
+ /**
132
+ * Queue a job. A queued or running job of the same type is returned instead,
133
+ * unless `dedupe` is false. Batch AI is never deduped.
134
+ */
135
+ export async function enqueueJob(store, input) {
136
+ const active = await findReusable(store, input.type, input.dedupe);
137
+ if (active)
138
+ return active;
139
+ return insertJob(store, input);
140
+ }
141
+ /**
142
+ * "Run now" from the Jobs screen. Same rule as cron: a queued or running job of
143
+ * the type is returned with `reused: true`. Batch AI never reuses one.
144
+ */
145
+ export async function runJobNow(store, input) {
146
+ const active = await findReusable(store, input.type);
147
+ if (active)
148
+ return { job: active, reused: true };
149
+ const job = await insertJob(store, { ...input, payload: { trigger: 'manual' } });
150
+ return { job, reused: false };
151
+ }
152
+ /**
153
+ * Put a dead job, or a queued job waiting out a failure, back in the queue now.
154
+ * Attempts reset and the handler continues from its saved cursor. Returns null
155
+ * when there is no such job, and `retried: false` with the job as it is when it
156
+ * can't be retried.
157
+ */
158
+ export async function retryJob(store, id, now) {
159
+ const retried = await store.retry(id, now);
160
+ const job = await store.get(id);
161
+ if (!job)
162
+ return null;
163
+ if (retried) {
164
+ await recordEvent(store, {
165
+ jobId: id,
166
+ at: now,
167
+ kind: 'queued',
168
+ message: 'Retried',
169
+ detail: 'Attempts reset. It continues from where it stopped.',
170
+ });
171
+ }
172
+ return { job, retried };
173
+ }
174
+ /** Resolves to `fallback` after `ms` if `work` hasn't settled, so a stuck call can't hold the tick. */
175
+ async function within(work, ms, fallback) {
176
+ let timer;
177
+ const late = new Promise((resolve) => {
178
+ timer = setTimeout(() => resolve(fallback), ms);
179
+ });
180
+ try {
181
+ return await Promise.race([work, late]);
182
+ }
183
+ finally {
184
+ clearTimeout(timer);
185
+ }
186
+ }
187
+ /**
188
+ * Write pending AI notes until `until`, oldest first. Each note is claimed
189
+ * before its AI call, so it gets one try per finish: a call that fails, times
190
+ * out or is cut off by the function ending leaves the note empty for good. No
191
+ * call starts with less than {@link NOTE_MIN_MS} left, and none runs past
192
+ * `until`.
193
+ */
194
+ async function writeNotes(store, notes, until, clock) {
195
+ const timeLeft = () => until.getTime() - clock().getTime() - NOTE_WRITE_MS;
196
+ if (!notes || timeLeft() < NOTE_MIN_MS)
197
+ return;
198
+ let pending;
199
+ try {
200
+ const since = new Date(clock().getTime() - NOTE_WINDOW_MS);
201
+ pending = await store.findPendingNotes(since, notes.summaryTypes, NOTE_BATCH);
202
+ }
203
+ catch {
204
+ return;
205
+ }
206
+ for (const job of pending) {
207
+ const left = timeLeft();
208
+ if (left < NOTE_MIN_MS)
209
+ return;
210
+ if (!job.finishedAt)
211
+ continue;
212
+ const note = job.status === 'dead' ? 'explain' : 'summary';
213
+ try {
214
+ if (!(await store.claimNote(job.id, note, job.finishedAt)))
215
+ continue;
216
+ const timeoutMs = Math.min(NOTE_TIMEOUT_MS, left);
217
+ const call = note === 'explain' ? notes.explain(job, timeoutMs) : notes.summarize(job, timeoutMs);
218
+ const out = await within(call.catch(() => ({ text: null })), timeoutMs, { text: null });
219
+ await store.writeNote(job.id, note, job.finishedAt, out.text ?? '', out.usage);
220
+ }
221
+ catch {
222
+ // Best effort: the job's status is already saved.
223
+ }
224
+ }
225
+ }
38
226
  /** Count a failure. Returns the row to queued with backoff, or dead-letters it. */
39
227
  async function failJob(store, job, error, now) {
40
228
  const attempts = job.attempts + 1;
41
229
  const dead = attempts >= job.maxAttempts;
230
+ const waitMs = backoffMs(attempts);
42
231
  const next = {
43
232
  ...job,
44
233
  attempts,
45
234
  status: dead ? 'dead' : 'queued',
46
- runAt: dead ? job.runAt : new Date(now.getTime() + backoffMs(attempts)),
235
+ runAt: dead ? job.runAt : new Date(now.getTime() + waitMs),
47
236
  lockedAt: null,
48
- lastError: error,
237
+ lastError: clipError(error),
238
+ finishedAt: dead ? now : null,
49
239
  updatedAt: now,
50
240
  };
51
241
  await store.save(next);
242
+ await recordEvent(store, dead
243
+ ? {
244
+ jobId: job.id,
245
+ at: now,
246
+ kind: 'dead',
247
+ message: 'Marked failed',
248
+ detail: `${attempts} of ${job.maxAttempts} attempts used. Finished work is kept.`,
249
+ }
250
+ : {
251
+ jobId: job.id,
252
+ at: now,
253
+ kind: 'retry_scheduled',
254
+ message: 'Retry scheduled',
255
+ detail: `Attempt ${attempts} of ${job.maxAttempts} failed. Next try in ${formatWait(waitMs)}.`,
256
+ });
257
+ if (dead)
258
+ await trimLog(store, job.id);
52
259
  return next;
53
260
  }
54
- /** A voluntary slice. Attempts stay put so a long job is not punished for yielding. */
55
- async function yieldJob(store, job, progress, payload, now) {
261
+ /**
262
+ * A failure while a cancel is pending ends the job as cancelled instead: attempts
263
+ * stay put, progress is kept and the error goes in `lastError`. Otherwise {@link failJob}.
264
+ */
265
+ async function failOrCancel(store, job, error, now) {
266
+ const toCancel = await cancelRequestedDuringSlice(store, job.id);
267
+ if (toCancel) {
268
+ return (await finalizeCancel(store, { ...toCancel, lastError: clipError(error) }, now)).job;
269
+ }
270
+ return failJob(store, job, error, now);
271
+ }
272
+ function countFailure(result, job) {
273
+ if (job.status === 'cancelled')
274
+ result.cancelled++;
275
+ else if (job.status === 'dead')
276
+ result.dead++;
277
+ else
278
+ result.retried++;
279
+ }
280
+ /**
281
+ * A voluntary slice. Attempts stay put so a long job is not punished for yielding.
282
+ * It runs again at `runAt`, which is now unless the handler asked to wait. The
283
+ * slice worked, so an earlier failure's `lastError` is cleared; its
284
+ * `slice_failed` event keeps the history.
285
+ */
286
+ async function yieldJob(store, job, progress, payload, now, runAt = now) {
56
287
  const next = {
57
288
  ...job,
58
289
  status: 'queued',
59
- runAt: now,
290
+ runAt,
60
291
  lockedAt: null,
292
+ lastError: null,
61
293
  progress,
62
294
  payload,
63
295
  updatedAt: now,
@@ -65,70 +297,214 @@ async function yieldJob(store, job, progress, payload, now) {
65
297
  await store.save(next);
66
298
  return next;
67
299
  }
68
- async function completeJob(store, job, progress, now) {
300
+ /** Saves a success, with a scan's results when the handler made them. */
301
+ async function completeJob(store, job, progress, now, results) {
69
302
  const next = {
70
303
  ...job,
71
304
  status: 'succeeded',
72
305
  lockedAt: null,
306
+ lastError: null,
307
+ ...(results ? { results } : {}),
73
308
  progress: progress ?? {
74
309
  completed: job.progress.total || 1,
75
310
  total: job.progress.total || 1,
76
311
  message: job.progress.message,
77
312
  },
313
+ finishedAt: now,
78
314
  updatedAt: now,
79
315
  };
80
316
  await store.save(next);
81
317
  return next;
82
318
  }
83
319
  export async function processJobQueue(options) {
320
+ const { store } = options;
84
321
  const clock = options.clock ?? (() => new Date());
85
322
  const started = options.now ?? clock();
86
323
  const budgetMs = options.budgetMs ?? DEFAULT_BUDGET_MS;
87
324
  const deadline = new Date(started.getTime() + budgetMs);
88
325
  const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
89
- const result = { succeeded: 0, continued: 0, retried: 0, dead: 0 };
326
+ const result = { succeeded: 0, continued: 0, retried: 0, dead: 0, cancelled: 0 };
327
+ // A stale lock is handled as a throw, so a pending cancel wins over the retry.
90
328
  const cutoff = new Date(started.getTime() - staleLockMs);
91
- for (const stale of await options.store.findStaleRunning(cutoff)) {
92
- const failed = await failJob(options.store, stale, 'Worker stopped before the job finished', started);
93
- if (failed.status === 'dead')
94
- result.dead++;
95
- else
96
- result.retried++;
329
+ for (const stale of await store.findStaleRunning(cutoff)) {
330
+ await recordEvent(store, {
331
+ jobId: stale.id,
332
+ at: started,
333
+ kind: 'stale_lock',
334
+ message: 'Worker stopped mid-slice',
335
+ detail: stale.lockedAt
336
+ ? `Locked at ${stale.lockedAt.toISOString()} and not released within ${formatWait(staleLockMs)}.`
337
+ : null,
338
+ });
339
+ const failed = await failOrCancel(store, stale, 'Worker stopped before the job finished', started);
340
+ countFailure(result, failed);
341
+ }
342
+ // Queued jobs only: a running job's cancel is finished by the tick that holds
343
+ // its lock, with that slice's work, or by the stale-lock path above.
344
+ for (const pendingCancel of await store.findCancelRequested()) {
345
+ if ((await finalizeCancel(store, pendingCancel, started)).applied)
346
+ result.cancelled++;
97
347
  }
348
+ // Notes left by earlier ticks, in up to half the budget, so a busy queue
349
+ // can't keep them waiting. Notes for jobs this tick ends follow the loop.
350
+ const leadUntil = new Date(started.getTime() + budgetMs * NOTE_LEAD_SHARE);
351
+ await writeNotes(store, options.notes, leadUntil, clock);
98
352
  while (clock().getTime() < deadline.getTime()) {
99
353
  const now = clock();
100
- const job = await options.store.claimNext(now);
354
+ const job = await store.claimNext(now);
101
355
  if (!job)
102
356
  break;
103
357
  const handler = options.handlers[job.type];
104
358
  if (!handler) {
105
- const failed = await failJob(options.store, job, `Unknown job type: ${job.type}`, now);
106
- if (failed.status === 'dead')
107
- result.dead++;
108
- else
109
- result.retried++;
359
+ const error = `Unknown job type: ${job.type}`;
360
+ await recordEvent(store, {
361
+ jobId: job.id,
362
+ at: now,
363
+ kind: 'slice_failed',
364
+ message: 'Slice failed',
365
+ detail: error,
366
+ });
367
+ const failed = await failOrCancel(store, job, error, now);
368
+ countFailure(result, failed);
110
369
  continue;
111
370
  }
371
+ const fresh = (await store.get(job.id)) ?? job;
372
+ if (fresh.cancelRequestedAt) {
373
+ if ((await finalizeCancel(store, fresh, now)).applied)
374
+ result.cancelled++;
375
+ continue;
376
+ }
377
+ await recordEvent(store, {
378
+ jobId: job.id,
379
+ at: now,
380
+ kind: 'claimed',
381
+ message: 'Slice started',
382
+ detail: fresh.attempts > 0 ? `Attempt ${fresh.attempts + 1} of ${fresh.maxAttempts}` : null,
383
+ });
112
384
  try {
113
- const outcome = await handler(job, { now, deadline });
385
+ const outcome = await handler(fresh, { now, deadline });
386
+ const endedAt = clock();
387
+ const durationMs = endedAt.getTime() - now.getTime();
388
+ const tokens = usageTokens(outcome.usage);
114
389
  if (outcome.done) {
115
- await completeJob(options.store, job, outcome.progress, clock());
390
+ // A slice that finished the job wins over a cancel that arrived while it ran.
391
+ const finished = await completeJob(store, addUsage(job, outcome.usage), outcome.progress, endedAt, outcome.results);
392
+ await recordEvent(store, {
393
+ jobId: job.id,
394
+ at: endedAt,
395
+ kind: 'finished',
396
+ message: 'Finished',
397
+ detail: finished.progress.message ?? null,
398
+ durationMs,
399
+ tokens,
400
+ });
401
+ await trimLog(store, job.id);
116
402
  result.succeeded++;
403
+ continue;
117
404
  }
118
- else {
119
- await yieldJob(options.store, job, outcome.progress, outcome.payload ?? job.payload, clock());
120
- result.continued++;
405
+ const payload = outcome.payload ?? job.payload;
406
+ const toCancel = await cancelRequestedDuringSlice(store, job.id);
407
+ if (toCancel) {
408
+ const ended = await finalizeCancel(store, {
409
+ ...addUsage(toCancel, outcome.usage),
410
+ lastError: null,
411
+ progress: outcome.progress,
412
+ payload,
413
+ }, endedAt);
414
+ if (ended.applied)
415
+ result.cancelled++;
416
+ continue;
121
417
  }
418
+ const wait = outcome.wait;
419
+ await yieldJob(store, addUsage(job, outcome.usage), outcome.progress, payload, endedAt, wait?.until);
420
+ await recordEvent(store, {
421
+ jobId: job.id,
422
+ at: endedAt,
423
+ kind: 'yielded',
424
+ message: wait ? 'Paused for a usage limit' : 'Slice finished',
425
+ detail: wait
426
+ ? `${wait.reason} Continues at ${wait.until.toISOString()}.`
427
+ : (outcome.progress.message ?? null),
428
+ durationMs,
429
+ tokens,
430
+ });
431
+ result.continued++;
122
432
  }
123
433
  catch (err) {
124
- const message = err instanceof Error ? err.message : String(err);
125
- const failed = await failJob(options.store, job, message, clock());
126
- if (failed.status === 'dead')
127
- result.dead++;
128
- else
129
- result.retried++;
434
+ const error = describeError(err);
435
+ const endedAt = clock();
436
+ await recordEvent(store, {
437
+ jobId: job.id,
438
+ at: endedAt,
439
+ kind: 'slice_failed',
440
+ message: 'Slice failed',
441
+ detail: error.summary,
442
+ durationMs: endedAt.getTime() - now.getTime(),
443
+ });
444
+ const failed = await failOrCancel(store, job, error.text, endedAt);
445
+ countFailure(result, failed);
130
446
  }
131
447
  }
448
+ await pruneOldJobs(store, started, deadline, clock);
449
+ await writeNotes(store, options.notes, deadline, clock);
132
450
  return result;
133
451
  }
452
+ /**
453
+ * Queued jobs cancel immediately. Running jobs stop at the next slice. Idempotent.
454
+ * A job that has already finished is returned unchanged, including one that
455
+ * finished between the read and the write here.
456
+ */
457
+ export async function requestJobCancel(store, id, byId, now) {
458
+ const job = await store.get(id);
459
+ if (!job)
460
+ return null;
461
+ if (job.status !== 'queued' && job.status !== 'running')
462
+ return job;
463
+ // Only the cancel fields are written, so the running slice's own save keeps them.
464
+ // The write is skipped if the job finished in the meantime.
465
+ const flaggedNow = await store.requestCancel(id, now, byId);
466
+ const flagged = (await store.get(id)) ?? job;
467
+ if (flagged.status === 'queued' && flagged.cancelRequestedAt) {
468
+ return (await finalizeCancel(store, flagged, now)).job;
469
+ }
470
+ if (flaggedNow && flagged.status === 'running') {
471
+ await recordEvent(store, {
472
+ jobId: id,
473
+ at: now,
474
+ kind: 'cancel_requested',
475
+ message: 'Cancel requested',
476
+ detail: 'It stops at the end of the current slice.',
477
+ });
478
+ }
479
+ return flagged;
480
+ }
481
+ /** The row as it is now, if a cancel was requested (for example while the slice ran). */
482
+ async function cancelRequestedDuringSlice(store, id) {
483
+ const latest = await store.get(id);
484
+ return latest?.cancelRequestedAt ? latest : null;
485
+ }
486
+ /** Progress and payload are kept. The cancel fields are already stored by requestCancel. */
487
+ async function finalizeCancel(store, job, now) {
488
+ const next = {
489
+ ...job,
490
+ status: 'cancelled',
491
+ finishedAt: now,
492
+ lockedAt: null,
493
+ updatedAt: now,
494
+ };
495
+ // Only while the row still waits on this cancel: a retry may have cleared the
496
+ // flag, or another caller may have finished the cancel already.
497
+ if (!(await store.finishCancel(next))) {
498
+ return { job: (await store.get(job.id)) ?? job, applied: false };
499
+ }
500
+ await recordEvent(store, {
501
+ jobId: job.id,
502
+ at: now,
503
+ kind: 'cancelled',
504
+ message: 'Cancelled',
505
+ detail: 'Work done so far is kept.',
506
+ });
507
+ await trimLog(store, job.id);
508
+ return { job: next, applied: true };
509
+ }
134
510
  //# sourceMappingURL=queue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/jobs/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The jobs one retention run deletes, from candidates oldest first: as many as
3
+ * fit while the events and review items they take with them stay within
4
+ * `maxRows`. The first is always taken, so one large job can't hold retention
5
+ * up for good.
6
+ */
7
+ export declare function withinRows(candidates: ReadonlyArray<{
8
+ id: string;
9
+ rows: number;
10
+ }>, maxRows: number): string[];
11
+ //# sourceMappingURL=retention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/jobs/retention.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACvD,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CASV"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The jobs one retention run deletes, from candidates oldest first: as many as
3
+ * fit while the events and review items they take with them stay within
4
+ * `maxRows`. The first is always taken, so one large job can't hold retention
5
+ * up for good.
6
+ */
7
+ export function withinRows(candidates, maxRows) {
8
+ const ids = [];
9
+ let rows = 0;
10
+ for (const candidate of candidates) {
11
+ rows += candidate.rows;
12
+ if (ids.length > 0 && rows > maxRows)
13
+ break;
14
+ ids.push(candidate.id);
15
+ }
16
+ return ids;
17
+ }
18
+ //# sourceMappingURL=retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention.js","sourceRoot":"","sources":["../../src/jobs/retention.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,UAAuD,EACvD,OAAe;IAEf,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAA;QACtB,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,GAAG,OAAO;YAAE,MAAK;QAC3C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IACxB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}