@aglyn/plugins-ai 1.0.0-beta.269 → 1.0.0-beta.271

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 (237) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.d.ts +1 -1
  3. package/src/lib/activity/ai-activity-actions.js +1 -0
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/assets/site-styles/beauty.webp +0 -0
  6. package/src/lib/assets/site-styles/blog.webp +0 -0
  7. package/src/lib/assets/site-styles/business.webp +0 -0
  8. package/src/lib/assets/site-styles/coming-soon.webp +0 -0
  9. package/src/lib/assets/site-styles/education.webp +0 -0
  10. package/src/lib/assets/site-styles/events.webp +0 -0
  11. package/src/lib/assets/site-styles/fitness.webp +0 -0
  12. package/src/lib/assets/site-styles/landing.webp +0 -0
  13. package/src/lib/assets/site-styles/music.webp +0 -0
  14. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  15. package/src/lib/assets/site-styles/personal.webp +0 -0
  16. package/src/lib/assets/site-styles/photography.webp +0 -0
  17. package/src/lib/assets/site-styles/portfolio.webp +0 -0
  18. package/src/lib/assets/site-styles/professional.webp +0 -0
  19. package/src/lib/assets/site-styles/realestate.webp +0 -0
  20. package/src/lib/assets/site-styles/restaurant.webp +0 -0
  21. package/src/lib/assets/site-styles/store.webp +0 -0
  22. package/src/lib/assets/site-styles/studio.webp +0 -0
  23. package/src/lib/assets/site-styles/trades.webp +0 -0
  24. package/src/lib/assets/site-styles/wellness.webp +0 -0
  25. package/src/lib/assets/site-styles/yoga.webp +0 -0
  26. package/src/lib/components/ai-credits-card.component.d.ts +8 -6
  27. package/src/lib/components/ai-credits-card.component.js +39 -22
  28. package/src/lib/components/ai-credits-card.component.js.map +1 -1
  29. package/src/lib/components/ai-job-input-form.component.d.ts +36 -0
  30. package/src/lib/components/ai-job-input-form.component.js +100 -0
  31. package/src/lib/components/ai-job-input-form.component.js.map +1 -0
  32. package/src/lib/components/ai-job-links.d.ts +6 -0
  33. package/src/lib/components/ai-job-links.js +9 -0
  34. package/src/lib/components/ai-job-links.js.map +1 -1
  35. package/src/lib/components/ai-job-requests.d.ts +4 -0
  36. package/src/lib/components/ai-job-requests.js +4 -0
  37. package/src/lib/components/ai-job-requests.js.map +1 -1
  38. package/src/lib/components/ai-products-hub-card.component.d.ts +6 -0
  39. package/src/lib/components/ai-products-hub-card.component.js +21 -6
  40. package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
  41. package/src/lib/components/ai-site-build-page.component.js +3 -2
  42. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  43. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  44. package/src/lib/components/ai-site-start-card.component.js +99 -31
  45. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  46. package/src/lib/components/ai-site-start-steps.component.d.ts +43 -2
  47. package/src/lib/components/ai-site-start-steps.component.js +651 -15
  48. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  49. package/src/lib/components/ai-site-start-tracking.d.ts +10 -0
  50. package/src/lib/components/ai-site-start-tracking.js +14 -0
  51. package/src/lib/components/ai-site-start-tracking.js.map +1 -1
  52. package/src/lib/components/ai-site-style-previews.js +26 -22
  53. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  54. package/src/lib/components/ai-store-finish-card.component.d.ts +14 -3
  55. package/src/lib/components/ai-store-finish-card.component.js +67 -9
  56. package/src/lib/components/ai-store-finish-card.component.js.map +1 -1
  57. package/src/lib/components/ai-upsell-dialog.component.d.ts +7 -5
  58. package/src/lib/components/ai-upsell-dialog.component.js +8 -6
  59. package/src/lib/components/ai-upsell-dialog.component.js.map +1 -1
  60. package/src/lib/components/assist-build-card.component.js +14 -3
  61. package/src/lib/components/assist-build-card.component.js.map +1 -1
  62. package/src/lib/components/assist-jobs-drawer.component.js +9 -1
  63. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  64. package/src/lib/components/assist-panel.component.js +8 -4
  65. package/src/lib/components/assist-panel.component.js.map +1 -1
  66. package/src/lib/components/staff-org-ai-card.component.js +4 -7
  67. package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
  68. package/src/lib/declarations.d.ts +2 -2
  69. package/src/lib/declarations.js +9 -5
  70. package/src/lib/declarations.js.map +1 -1
  71. package/src/lib/jobs/ai-build-capabilities.js +3 -1
  72. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  73. package/src/lib/jobs/ai-business-profile-prefill.d.ts +1 -1
  74. package/src/lib/jobs/ai-business-profile-prefill.js +14 -3
  75. package/src/lib/jobs/ai-business-profile-prefill.js.map +1 -1
  76. package/src/lib/jobs/ai-job-build-step.d.ts +3 -0
  77. package/src/lib/jobs/ai-job-build-step.js +13 -5
  78. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  79. package/src/lib/jobs/ai-job-form-step.d.ts +24 -1
  80. package/src/lib/jobs/ai-job-form-step.js +93 -7
  81. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  82. package/src/lib/jobs/ai-job-page-language.d.ts +35 -11
  83. package/src/lib/jobs/ai-job-page-language.js +68 -2
  84. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  85. package/src/lib/jobs/ai-job-page-step.d.ts +17 -0
  86. package/src/lib/jobs/ai-job-page-step.js +40 -17
  87. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  88. package/src/lib/jobs/ai-job-plan-step.d.ts +25 -2
  89. package/src/lib/jobs/ai-job-plan-step.js +103 -29
  90. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  91. package/src/lib/jobs/ai-job-settings-step.js +4 -3
  92. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  93. package/src/lib/jobs/ai-job-site-datasets.d.ts +27 -0
  94. package/src/lib/jobs/ai-job-site-datasets.js +140 -14
  95. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  96. package/src/lib/jobs/ai-job-site-look.js +18 -5
  97. package/src/lib/jobs/ai-job-site-look.js.map +1 -1
  98. package/src/lib/jobs/ai-job-site-step.d.ts +16 -1
  99. package/src/lib/jobs/ai-job-site-step.js +95 -22
  100. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  101. package/src/lib/jobs/ai-job-text-step.d.ts +8 -1
  102. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  103. package/src/lib/jobs/ai-job-tracking-step.d.ts +14 -3
  104. package/src/lib/jobs/ai-job-tracking-step.js +28 -5
  105. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
  106. package/src/lib/jobs/ai-jobs.d.ts +8 -1
  107. package/src/lib/jobs/ai-jobs.js +63 -8
  108. package/src/lib/jobs/ai-jobs.js.map +1 -1
  109. package/src/lib/jobs/ai-layout-owner-photos.d.ts +57 -0
  110. package/src/lib/jobs/ai-layout-owner-photos.js +110 -0
  111. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -0
  112. package/src/lib/jobs/ai-layout-stock-photos.d.ts +62 -4
  113. package/src/lib/jobs/ai-layout-stock-photos.js +523 -72
  114. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  115. package/src/lib/jobs/ai-site-inspiration-signals.d.ts +98 -0
  116. package/src/lib/jobs/ai-site-inspiration-signals.js +585 -0
  117. package/src/lib/jobs/ai-site-inspiration-signals.js.map +1 -0
  118. package/src/lib/jobs/ai-site-inspiration.d.ts +157 -0
  119. package/src/lib/jobs/ai-site-inspiration.js +346 -0
  120. package/src/lib/jobs/ai-site-inspiration.js.map +1 -0
  121. package/src/lib/jobs/ai-site-publish.d.ts +26 -1
  122. package/src/lib/jobs/ai-site-publish.js +162 -13
  123. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  124. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +16 -0
  125. package/src/lib/jobs/ai-theme-brand-inputs.js +18 -4
  126. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  127. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.d.ts +97 -0
  128. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js +137 -0
  129. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js.map +1 -0
  130. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.d.ts +38 -0
  131. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js +103 -0
  132. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js.map +1 -0
  133. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.d.ts +29 -0
  134. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js +291 -0
  135. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js.map +1 -0
  136. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.d.ts +25 -0
  137. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js +174 -0
  138. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js.map +1 -0
  139. package/src/lib/layout-language/ai-layout-compiler.d.ts +1 -1
  140. package/src/lib/layout-language/ai-layout-compiler.js +438 -25
  141. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  142. package/src/lib/layout-language/ai-layout-contact.d.ts +57 -0
  143. package/src/lib/layout-language/ai-layout-contact.js +137 -0
  144. package/src/lib/layout-language/ai-layout-contact.js.map +1 -0
  145. package/src/lib/layout-language/ai-layout-copy.d.ts +12 -0
  146. package/src/lib/layout-language/ai-layout-copy.js +34 -2
  147. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  148. package/src/lib/layout-language/ai-layout-design.d.ts +65 -8
  149. package/src/lib/layout-language/ai-layout-design.js +411 -97
  150. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  151. package/src/lib/layout-language/ai-layout-frame.js +23 -0
  152. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  153. package/src/lib/layout-language/ai-layout-labels.d.ts +2 -0
  154. package/src/lib/layout-language/ai-layout-labels.js +12 -6
  155. package/src/lib/layout-language/ai-layout-labels.js.map +1 -1
  156. package/src/lib/layout-language/ai-layout-language.d.ts +3 -2
  157. package/src/lib/layout-language/ai-layout-language.js +4 -3
  158. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  159. package/src/lib/layout-language/ai-layout-links.d.ts +13 -0
  160. package/src/lib/layout-language/ai-layout-links.js +30 -0
  161. package/src/lib/layout-language/ai-layout-links.js.map +1 -1
  162. package/src/lib/layout-language/ai-layout-pictures.d.ts +49 -6
  163. package/src/lib/layout-language/ai-layout-pictures.js +145 -22
  164. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  165. package/src/lib/model/ai-build-job.d.ts +16 -1
  166. package/src/lib/model/ai-build-job.js +40 -0
  167. package/src/lib/model/ai-build-job.js.map +1 -1
  168. package/src/lib/model/ai-job-input.d.ts +33 -0
  169. package/src/lib/model/ai-job-input.js +59 -0
  170. package/src/lib/model/ai-job-input.js.map +1 -0
  171. package/src/lib/model/ai-job-notice.d.ts +4 -0
  172. package/src/lib/model/ai-job-notice.js +11 -1
  173. package/src/lib/model/ai-job-notice.js.map +1 -1
  174. package/src/lib/model/ai-jobs.types.d.ts +40 -1
  175. package/src/lib/model/ai-jobs.types.js.map +1 -1
  176. package/src/lib/model/ai-site-details.d.ts +122 -0
  177. package/src/lib/model/ai-site-details.js +300 -0
  178. package/src/lib/model/ai-site-details.js.map +1 -0
  179. package/src/lib/model/ai-site-entity.d.ts +181 -0
  180. package/src/lib/model/ai-site-entity.js +390 -0
  181. package/src/lib/model/ai-site-entity.js.map +1 -0
  182. package/src/lib/model/ai-site-inspiration.d.ts +72 -0
  183. package/src/lib/model/ai-site-inspiration.js +109 -0
  184. package/src/lib/model/ai-site-inspiration.js.map +1 -0
  185. package/src/lib/model/ai-site-job.d.ts +13 -1
  186. package/src/lib/model/ai-site-job.js +15 -2
  187. package/src/lib/model/ai-site-job.js.map +1 -1
  188. package/src/lib/model/ai-site-kinds.js +109 -21
  189. package/src/lib/model/ai-site-kinds.js.map +1 -1
  190. package/src/lib/model/ai-site-look.d.ts +10 -0
  191. package/src/lib/model/ai-site-look.js +24 -0
  192. package/src/lib/model/ai-site-look.js.map +1 -1
  193. package/src/lib/model/ai-site-start-seo.d.ts +19 -5
  194. package/src/lib/model/ai-site-start-seo.js +25 -7
  195. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  196. package/src/lib/model/ai-site-start-steps.d.ts +9 -3
  197. package/src/lib/model/ai-site-start-steps.js +67 -5
  198. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  199. package/src/lib/model/ai-site-start.d.ts +68 -4
  200. package/src/lib/model/ai-site-start.js +166 -13
  201. package/src/lib/model/ai-site-start.js.map +1 -1
  202. package/src/lib/model/ai-upsell-copy.js +4 -1
  203. package/src/lib/model/ai-upsell-copy.js.map +1 -1
  204. package/src/lib/native-nav.d.ts +26 -0
  205. package/src/lib/native-nav.js +58 -0
  206. package/src/lib/native-nav.js.map +1 -0
  207. package/src/lib/plan-entitlements.d.ts +4 -3
  208. package/src/lib/plan-entitlements.js +3 -8
  209. package/src/lib/plan-entitlements.js.map +1 -1
  210. package/src/lib/runtime/ai-dataset-generation.d.ts +8 -1
  211. package/src/lib/runtime/ai-dataset-generation.js +12 -2
  212. package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
  213. package/src/lib/runtime/ai-doctrine-validators.d.ts +26 -33
  214. package/src/lib/runtime/ai-doctrine-validators.js +54 -44
  215. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  216. package/src/lib/runtime/ai-doctrine.js +1 -1
  217. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  218. package/src/lib/runtime/ai-node-tree.d.ts +7 -0
  219. package/src/lib/runtime/ai-node-tree.js +9 -1
  220. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  221. package/src/lib/server/ai-create-route.d.ts +1 -1
  222. package/src/lib/server/ai-create-route.js +3 -4
  223. package/src/lib/server/ai-create-route.js.map +1 -1
  224. package/src/lib/server/ai-jobs-resume.js +27 -3
  225. package/src/lib/server/ai-jobs-resume.js.map +1 -1
  226. package/src/lib/server/ai-jobs-route.js +7 -0
  227. package/src/lib/server/ai-jobs-route.js.map +1 -1
  228. package/src/lib/usage/assist-credits.d.ts +4 -4
  229. package/src/lib/usage/assist-credits.js +4 -4
  230. package/src/lib/usage/assist-credits.js.map +1 -1
  231. package/src/lib/usage/staff-org-ai-view.js +6 -3
  232. package/src/lib/usage/staff-org-ai-view.js.map +1 -1
  233. package/src/lib/usage/staff-org-ai.d.ts +4 -2
  234. package/src/lib/usage/staff-org-ai.js +7 -7
  235. package/src/lib/usage/staff-org-ai.js.map +1 -1
  236. package/src/lib/usage/staff-org-usage-ai.js +2 -2
  237. package/src/lib/usage/staff-org-usage-ai.js.map +1 -1
@@ -24,6 +24,7 @@ import { createResourceUid } from "@aglyn/aglyn/app-utils/create-resource-uid";
24
24
  import { checkEntitlement } from "@aglyn/aglyn/server";
25
25
  import { assistCreditsFromUsd, assistFreeTasteRefusalText, assistHardCapRefusalText, assistRefusedByHardCap } from "../usage/assist-credits.js";
26
26
  import { AI_JOB_PLAN_STEP, AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
27
+ import { aiJobInputProblems, aiPlanWithInput } from "../model/ai-job-input.js";
27
28
  import { resolveEffectivePlan } from "@aglyn/aglyn/app-utils/plan-entitlements";
28
29
  import { aiOverageReservationRefusal } from "../billing/ai-overage-gate.js";
29
30
  import { aiAllotmentRefusalText } from "../model/ai-allotments.js";
@@ -478,7 +479,7 @@ export async function getAiJob(firestore, orgId, jobId) {
478
479
  }
479
480
  /** The wire form. `running` is the lease, read against `now`. */ export function aiJobSummary(job, now = new Date()) {
480
481
  var _job_hostId, _job_steps, _job_outputs, _job_creditsReserved, _job_creditsSpent, _job_refundedCredits, _toIso, _toIso1, _job_error, _job_plan_labels, _job_plan_confirmedBy, _job_applied_versions, _job_applied_staged;
481
- var _job_lease, _job_inputs, _job_items, _job_inputs1;
482
+ var _job_lease, _job_inputs, _job_input_fields, _job_input, _job_items, _job_inputs1;
482
483
  const leaseUntil = toMillis((_job_lease = job.lease) == null ? void 0 : _job_lease.until);
483
484
  return _extends({
484
485
  id: job.$id,
@@ -519,7 +520,10 @@ export async function getAiJob(firestore, orgId, jobId) {
519
520
  }) : null,
520
521
  review: job.review ? aiCustomerSafeReview(job.review, {
521
522
  page: job.kind === 'page'
522
- }) : null,
523
+ }) : null
524
+ }, job.status === 'needs_input' && ((_job_input = job.input) == null ? void 0 : (_job_input_fields = _job_input.fields) == null ? void 0 : _job_input_fields.length) ? {
525
+ input: job.input
526
+ } : {}, {
523
527
  applied: job.applied ? {
524
528
  at: toIso(job.applied.at),
525
529
  by: job.applied.by,
@@ -830,7 +834,7 @@ function nextStepIndex(job) {
830
834
  */ export async function recordStep(firestore, orgId, jobId, owner, stepIndex, input, now = new Date()) {
831
835
  const ref = jobsCollection(firestore, orgId).doc(jobId);
832
836
  const recorded = await firestore.runTransaction(async (tx)=>{
833
- var _ref, _input_items, _job_outputs, _input_outputs, _job_creditsSpent, _job_creditsReserved, _job_creditsReserved1, _job_refundedCredits, _ref1;
837
+ var _ref, _input_items, _job_outputs, _input_outputs, _job_creditsSpent, _job_creditsReserved, _job_creditsReserved1, _job_refundedCredits, _input_input, _ref1;
834
838
  var _job_lease, _input_item, _this;
835
839
  const job = jobFrom(await tx.get(ref));
836
840
  if (!job) throw new Error(`ai job ${orgId}/${jobId} vanished`);
@@ -858,7 +862,9 @@ function nextStepIndex(job) {
858
862
  // write that records what the step cost and built: nothing after it runs.
859
863
  const canceling = aiJobCancelPending(job);
860
864
  const parksForReview = Boolean(input.review) && !isAiJobTerminal(job.status) && !canceling;
861
- const status = isAiJobTerminal(job.status) ? job.status : canceling ? 'canceled' : job.status === 'needs_input' ? job.status : parksForReview ? 'needs_review' : input.status === 'failed' ? 'running' : remaining > 0 ? 'queued' : 'running';
865
+ // A plan only the person can complete waits for their answer (AGL-3978).
866
+ const parkedAs = input.input ? 'needs_input' : 'needs_review';
867
+ const status = isAiJobTerminal(job.status) ? job.status : canceling ? 'canceled' : job.status === 'needs_input' ? job.status : parksForReview ? parkedAs : input.status === 'failed' ? 'running' : remaining > 0 ? 'queued' : 'running';
862
868
  const patch = _extends({
863
869
  status,
864
870
  steps,
@@ -883,7 +889,8 @@ function nextStepIndex(job) {
883
889
  refundedCredits: ((_job_refundedCredits = job.refundedCredits) != null ? _job_refundedCredits : 0) + input.item.creditsRefunded
884
890
  } : {}, parksForReview && input.review ? {
885
891
  review: input.review,
886
- error: input.review.reason === 'plan' ? null : input.review.message
892
+ error: input.input ? input.input.message : input.review.reason === 'plan' ? null : input.review.message,
893
+ input: (_input_input = input.input) != null ? _input_input : null
887
894
  } : {}, canceling ? _extends({
888
895
  creditsReserved: 0,
889
896
  lease: null,
@@ -900,8 +907,8 @@ function nextStepIndex(job) {
900
907
  return {
901
908
  job: _extends({}, job, patch),
902
909
  remaining,
903
- // Entered `needs_review` in this write, rather than parked again.
904
- parked: parksForReview && job.status !== 'needs_review',
910
+ // Entered `needs_review` (or `needs_input` for an answer) in this write, rather than parked again.
911
+ parked: parksForReview && job.status !== parkedAs,
905
912
  // Ended `canceled` in this write (AGL-3936).
906
913
  ended: canceling && !isAiJobTerminal(job.status)
907
914
  };
@@ -1426,11 +1433,27 @@ async function transition(firestore, orgId, jobId, apply) {
1426
1433
  */ export async function resumeAiJob(firestore, orgId, jobId, actor, now = new Date(), options = {}) {
1427
1434
  const resumed = await transition(firestore, orgId, jobId, (current)=>{
1428
1435
  var _options_reducePlan;
1429
- var _current_review, _current_inputs;
1436
+ var _current_input_fields, _current_input, _current_review, _current_inputs;
1430
1437
  // A job the meter paused (AGL-3660) carries on from the step it paused
1431
1438
  // on: that step is already pending, so it is queued again with nothing
1432
1439
  // else changed. Whether the credits are there now is the reservation's
1433
1440
  // to say, at the door and again at the step.
1441
+ // A job waiting for a person's answer (AGL-3978) takes it only once every
1442
+ // field reads (`aiJobInputProblems`, which the door asks first): the
1443
+ // answer is written to the plan's item and the job returns to its plan
1444
+ // card, where Confirm builds it as any plan.
1445
+ if (current.status === 'needs_input' && ((_current_input = current.input) == null ? void 0 : (_current_input_fields = _current_input.fields) == null ? void 0 : _current_input_fields.length)) {
1446
+ const values = options.input;
1447
+ if (!values || !current.plan || Object.keys(aiJobInputProblems(current.input, values)).length) return null;
1448
+ return {
1449
+ status: 'needs_review',
1450
+ plan: aiPlanWithInput(current.plan, current.input, values),
1451
+ input: null,
1452
+ error: null,
1453
+ lease: null,
1454
+ updatedAt: now
1455
+ };
1456
+ }
1434
1457
  if (current.status === 'needs_input') {
1435
1458
  return {
1436
1459
  status: 'queued',
@@ -2004,6 +2027,8 @@ async function transition(firestore, orgId, jobId, apply) {
2004
2027
  plan: outcome.plan
2005
2028
  } : {}, review ? {
2006
2029
  review
2030
+ } : {}, review && outcome.input ? {
2031
+ input: outcome.input
2007
2032
  } : {}, outcome.sitePublish ? {
2008
2033
  sitePublish: outcome.sitePublish
2009
2034
  } : {}, aiJobSettlesByItem(job.kind) && outcome.items ? {
@@ -2072,6 +2097,22 @@ async function transition(firestore, orgId, jobId, apply) {
2072
2097
  job: resumed.job
2073
2098
  };
2074
2099
  }
2100
+ // A plan waiting for an answer only the person can give (AGL-3978): kept,
2101
+ // charged as any plan is, and asked of them; nothing about it failed.
2102
+ if (review && outcome.input && recorded.job.status === 'needs_input') {
2103
+ await logAiJobNeedsInput(orgId, {
2104
+ uid: null
2105
+ }, {
2106
+ jobId,
2107
+ kind: job.kind,
2108
+ reason: 'input'
2109
+ });
2110
+ if (recorded.parked) await announceAiJobTransition(recorded.job, 'needs-review');
2111
+ return {
2112
+ outcome: 'needs_input',
2113
+ job: recorded.job
2114
+ };
2115
+ }
2075
2116
  if (review && recorded.job.status === 'needs_review') {
2076
2117
  var _reservation_free6;
2077
2118
  // Nobody parked the job but its own step, so the row names no actor, as
@@ -2199,6 +2240,7 @@ async function transition(firestore, orgId, jobId, apply) {
2199
2240
  const attempt = async (candidate, left, first)=>{
2200
2241
  const { orgId, jobId } = candidate;
2201
2242
  try {
2243
+ var _current_input_fields, _current_input;
2202
2244
  const current = await getAiJob(options.firestore, orgId, jobId);
2203
2245
  // A step that needs more time than is left is not started (AGL-2907): a
2204
2246
  // provider call the abort cuts off is billed upstream and metered
@@ -2209,6 +2251,19 @@ async function transition(firestore, orgId, jobId, apply) {
2209
2251
  if (first) result.remaining += 1;
2210
2252
  return;
2211
2253
  }
2254
+ // A job waiting for a person's answer (AGL-3978) is theirs to resume:
2255
+ // it rests again, at the back of the parked queue, so it never holds a
2256
+ // place a meter park could use.
2257
+ if ((current == null ? void 0 : current.status) === 'needs_input' && ((_current_input = current.input) == null ? void 0 : (_current_input_fields = _current_input.fields) == null ? void 0 : _current_input_fields.length)) {
2258
+ await transition(options.firestore, orgId, jobId, (job)=>{
2259
+ var _job_input_fields, _job_input;
2260
+ return job.status === 'needs_input' && ((_job_input = job.input) == null ? void 0 : (_job_input_fields = _job_input.fields) == null ? void 0 : _job_input_fields.length) ? {
2261
+ updatedAt: new Date(now())
2262
+ } : null;
2263
+ });
2264
+ if (first) result.skipped += 1;
2265
+ return;
2266
+ }
2212
2267
  if ((current == null ? void 0 : current.status) === 'needs_input') {
2213
2268
  await transition(options.firestore, orgId, jobId, (job)=>job.status === 'needs_input' ? {
2214
2269
  status: 'queued',