@dsh-enhanced/assistant-work-items 0.1.67 → 0.1.70

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 (44) hide show
  1. package/README.md +17 -10
  2. package/lib/acceptance-binding.d.ts +3 -1
  3. package/lib/acceptance-binding.d.ts.map +1 -1
  4. package/lib/acceptance-binding.js +26 -1
  5. package/lib/acceptance-binding.js.map +1 -1
  6. package/lib/continuation-contract.d.ts +1 -1
  7. package/lib/continuation-contract.d.ts.map +1 -1
  8. package/lib/continuation-contract.js +5 -2
  9. package/lib/continuation-contract.js.map +1 -1
  10. package/lib/continuation.d.ts.map +1 -1
  11. package/lib/continuation.js +7 -2
  12. package/lib/continuation.js.map +1 -1
  13. package/lib/dispatch.d.ts +6 -16
  14. package/lib/dispatch.d.ts.map +1 -1
  15. package/lib/dispatch.js +14 -18
  16. package/lib/dispatch.js.map +1 -1
  17. package/lib/intake-admission.d.ts +28 -2
  18. package/lib/intake-admission.d.ts.map +1 -1
  19. package/lib/intake-admission.js +22 -4
  20. package/lib/intake-admission.js.map +1 -1
  21. package/lib/intake.d.ts +38 -0
  22. package/lib/intake.d.ts.map +1 -1
  23. package/lib/intake.js +55 -1
  24. package/lib/intake.js.map +1 -1
  25. package/lib/mandate.d.ts.map +1 -1
  26. package/lib/mandate.js +4 -0
  27. package/lib/mandate.js.map +1 -1
  28. package/lib/reply-contract.d.ts +1 -1
  29. package/lib/reply-contract.d.ts.map +1 -1
  30. package/lib/reply-contract.js +2 -2
  31. package/lib/reply-contract.js.map +1 -1
  32. package/lib/service.d.ts +22 -35
  33. package/lib/service.d.ts.map +1 -1
  34. package/lib/service.js +118 -105
  35. package/lib/service.js.map +1 -1
  36. package/lib/store.d.ts +3 -3
  37. package/lib/store.d.ts.map +1 -1
  38. package/lib/store.js +13 -6
  39. package/lib/store.js.map +1 -1
  40. package/lib/types.d.ts +3 -1
  41. package/lib/types.d.ts.map +1 -1
  42. package/lib/version.d.ts +1 -1
  43. package/lib/version.js +1 -1
  44. package/package.json +7 -7
package/lib/store.js CHANGED
@@ -1211,18 +1211,20 @@ export class WorkItemStore {
1211
1211
  }
1212
1212
  /**
1213
1213
  * WP21 slice 6 candidates: items whose worker dispatch is `dispatched` to
1214
- * `workerAutomationId` under their current occurrence, whose mandate binds
1214
+ * their configured main or continuation worker under the current occurrence, whose mandate binds
1215
1215
  * no contract, that have no verdict yet and no `acceptance-bound` row for
1216
1216
  * that occurrence. Never-run, withdrawn, failed and dropped items are out.
1217
1217
  * (created_at, id) order strictly after `after`; bounded scan, no schema change.
1218
1218
  */
1219
- listLateAcceptanceCandidates(workerAutomationId, after, limit) {
1219
+ listLateAcceptanceCandidates(workerAutomationId, after, limit, continuationAutomationId) {
1220
1220
  if (!Number.isSafeInteger(limit) || limit < 1 || limit > 10)
1221
1221
  fail('invalid-input', 'acceptance bind limit must be between 1 and 10');
1222
1222
  const rows = this.#statement(`
1223
1223
  SELECT ${ITEM_ALIASES} FROM work_item i
1224
1224
  WHERE EXISTS (SELECT 1 FROM work_item_dispatch d WHERE d.item_id = i.id AND d.state = 'dispatched'
1225
- AND d.occurrence_id IS NOT NULL AND d.occurrence_id = i.occurrence_id AND (d.automation_id = ? OR d.automation_id = ''))
1225
+ AND d.occurrence_id IS NOT NULL AND d.occurrence_id = i.occurrence_id
1226
+ AND ((d.automation_id = i.worker_automation_id AND d.automation_id IN (?, ?))
1227
+ OR (d.automation_id = '' AND i.worker_automation_id = ?)))
1226
1228
  AND i.state NOT IN ('failed', 'dropped')
1227
1229
  AND CASE WHEN json_valid(i.authority_basis) THEN json_extract(i.authority_basis, '$.mandate.acceptance') END IS NULL
1228
1230
  AND NOT EXISTS (SELECT 1 FROM work_item_event e WHERE e.item_id = i.id AND e.kind = '${ACCEPTANCE_VERIFIED_EVENT}')
@@ -1230,14 +1232,18 @@ export class WorkItemStore {
1230
1232
  AND CASE WHEN json_valid(e.detail) THEN json_extract(e.detail, '$.occurrenceId') END = i.occurrence_id)
1231
1233
  AND (i.created_at, i.id) > (?, ?)
1232
1234
  ORDER BY i.created_at ASC, i.id ASC LIMIT ?
1233
- `).all(workerAutomationId, after?.createdAt ?? -1, after?.id ?? '', limit);
1235
+ `).all(workerAutomationId, continuationAutomationId ?? null, workerAutomationId, after?.createdAt ?? -1, after?.id ?? '', limit);
1234
1236
  const candidates = [];
1235
1237
  for (const row of rows) {
1236
1238
  const item = itemFromRow(row);
1237
1239
  const dispatch = this.getDispatch(item.id);
1238
1240
  if (dispatch?.state !== 'dispatched' || dispatch.occurrenceId === null || dispatch.occurrenceId !== item.occurrenceId)
1239
1241
  continue;
1240
- candidates.push(Object.freeze({ item, automationId: dispatch.automationId === '' ? workerAutomationId : dispatch.automationId, occurrenceId: dispatch.occurrenceId,
1242
+ // Empty dispatch IDs predate explicit worker IDs and belong only to the main worker.
1243
+ const automationId = dispatch.automationId === '' ? workerAutomationId : dispatch.automationId;
1244
+ if (automationId !== item.workerAutomationId || (automationId !== workerAutomationId && automationId !== continuationAutomationId))
1245
+ continue;
1246
+ candidates.push(Object.freeze({ item, automationId, occurrenceId: dispatch.occurrenceId,
1241
1247
  // This generation was armed at `occurredAt` (a re-arm sets it to the
1242
1248
  // re-arm or resume-due time) and is woken no earlier, so its run
1243
1249
  // cannot have started before it or before the item existed.
@@ -1328,7 +1334,7 @@ export class WorkItemStore {
1328
1334
  * position instead of rescanning rows that are still waiting. Read-only and
1329
1335
  * bounded; no schema change.
1330
1336
  */
1331
- listHeldAcceptanceReports(limit, after) {
1337
+ listHeldAcceptanceReports(limit, after, continuationOnly = false) {
1332
1338
  if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
1333
1339
  fail('invalid-input', 'held report limit must be between 1 and 100');
1334
1340
  const keyset = after === undefined ? '' : ' AND (r.recorded_at > ? OR (r.recorded_at = ? AND i.id > ?))';
@@ -1341,6 +1347,7 @@ export class WorkItemStore {
1341
1347
  AND r.status = 'ready' AND r.delivery_state IS NULL
1342
1348
  AND i.observed = 0 AND i.attempt >= 1
1343
1349
  AND (i.state = 'ready' OR (i.state = 'blocked' AND i.state_reason LIKE 'acceptance-%'))
1350
+ ${continuationOnly ? "AND i.kind = 'owner-continuation'" : ''}
1344
1351
  ${keyset}
1345
1352
  ORDER BY r.recorded_at ASC, i.id ASC LIMIT ?
1346
1353
  `).all(...(after === undefined ? [] : [after.recordedAt, after.recordedAt, after.itemId]), limit);