@agent-native/core 0.130.0 → 0.130.1

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 (63) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +6 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/integrations/a2a-continuation-processor.ts +481 -122
  5. package/corpus/core/src/integrations/a2a-continuations-store.ts +345 -14
  6. package/corpus/core/src/integrations/adapters/slack.ts +243 -53
  7. package/corpus/core/src/integrations/integration-campaign-recovery.ts +4 -1
  8. package/corpus/core/src/integrations/plugin.ts +39 -21
  9. package/corpus/core/src/integrations/task-queue-stats.ts +146 -0
  10. package/corpus/core/src/integrations/types.ts +25 -4
  11. package/corpus/core/src/integrations/webhook-handler.ts +18 -5
  12. package/corpus/templates/dispatch/changelog/2026-07-26-slack-replies-recover-after-connected-app-updates.md +6 -0
  13. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +15 -0
  14. package/corpus/templates/slides/actions/delete-design-system.ts +145 -0
  15. package/corpus/templates/slides/actions/list-design-systems.ts +94 -2
  16. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +43 -1
  17. package/corpus/templates/slides/app/hooks/use-design-systems.ts +2 -0
  18. package/corpus/templates/slides/app/i18n/en-US.ts +7 -0
  19. package/corpus/templates/slides/app/pages/DesignSystems.tsx +56 -1
  20. package/corpus/templates/slides/changelog/2026-07-28-delete-a-design-system-you-own-from-the-design-systems-page-.md +6 -0
  21. package/dist/collab/struct-routes.d.ts +1 -1
  22. package/dist/integrations/a2a-continuation-processor.d.ts +5 -0
  23. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  24. package/dist/integrations/a2a-continuation-processor.js +293 -79
  25. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  26. package/dist/integrations/a2a-continuations-store.d.ts +23 -1
  27. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  28. package/dist/integrations/a2a-continuations-store.js +249 -15
  29. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  30. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  31. package/dist/integrations/adapters/slack.js +155 -31
  32. package/dist/integrations/adapters/slack.js.map +1 -1
  33. package/dist/integrations/integration-campaign-recovery.d.ts.map +1 -1
  34. package/dist/integrations/integration-campaign-recovery.js +3 -1
  35. package/dist/integrations/integration-campaign-recovery.js.map +1 -1
  36. package/dist/integrations/plugin.d.ts.map +1 -1
  37. package/dist/integrations/plugin.js +29 -12
  38. package/dist/integrations/plugin.js.map +1 -1
  39. package/dist/integrations/task-queue-stats.d.ts +12 -0
  40. package/dist/integrations/task-queue-stats.d.ts.map +1 -1
  41. package/dist/integrations/task-queue-stats.js +106 -0
  42. package/dist/integrations/task-queue-stats.js.map +1 -1
  43. package/dist/integrations/types.d.ts +24 -6
  44. package/dist/integrations/types.d.ts.map +1 -1
  45. package/dist/integrations/types.js.map +1 -1
  46. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  47. package/dist/integrations/webhook-handler.js +12 -3
  48. package/dist/integrations/webhook-handler.js.map +1 -1
  49. package/dist/observability/routes.d.ts +3 -3
  50. package/dist/progress/routes.d.ts +1 -1
  51. package/dist/resources/handlers.d.ts +1 -1
  52. package/dist/secrets/routes.d.ts +9 -9
  53. package/dist/server/realtime-token.d.ts +1 -1
  54. package/dist/server/transcribe-voice.d.ts +1 -1
  55. package/package.json +1 -1
  56. package/src/integrations/a2a-continuation-processor.ts +481 -122
  57. package/src/integrations/a2a-continuations-store.ts +345 -14
  58. package/src/integrations/adapters/slack.ts +243 -53
  59. package/src/integrations/integration-campaign-recovery.ts +4 -1
  60. package/src/integrations/plugin.ts +39 -21
  61. package/src/integrations/task-queue-stats.ts +146 -0
  62. package/src/integrations/types.ts +25 -4
  63. package/src/integrations/webhook-handler.ts +18 -5
@@ -1 +1 @@
1
- {"version":3,"file":"integration-campaign-recovery.d.ts","sourceRoot":"","sources":["../../src/integrations/integration-campaign-recovery.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAiBD;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAkF7C"}
1
+ {"version":3,"file":"integration-campaign-recovery.d.ts","sourceRoot":"","sources":["../../src/integrations/integration-campaign-recovery.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAiBD;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAoF7C"}
@@ -1,3 +1,4 @@
1
+ import { getA2AContinuationTaskOutcome } from "./a2a-continuations-store.js";
1
2
  import { getIntegrationCampaign, failDisabledIntegrationCampaignTask, listDueIntegrationCampaignIds, } from "./integration-campaigns-store.js";
2
3
  import { dispatchPendingIntegrationTask, isIntegrationDurableDispatchEnabledForTask, } from "./integration-durable-dispatch.js";
3
4
  import { getNextPendingTaskForThread, getPendingTask, } from "./pending-tasks-store.js";
@@ -42,7 +43,8 @@ export async function recoverDueIntegrationCampaigns(options) {
42
43
  ? { channelId: task.dispatchScope }
43
44
  : undefined,
44
45
  });
45
- const confirmedReceipt = hasConfirmedDeliveryReceipt(task.payload);
46
+ const confirmedReceipt = hasConfirmedDeliveryReceipt(task.payload) ||
47
+ (await getA2AContinuationTaskOutcome(task.id)) === "terminal-delivered";
46
48
  if (!durableDispatchEnabled && !confirmedReceipt) {
47
49
  await failDisabledIntegrationCampaignTask(task.id);
48
50
  const nextTask = await getNextPendingTaskForThread(task.platform, task.externalThreadId);
@@ -1 +1 @@
1
- {"version":3,"file":"integration-campaign-recovery.js","sourceRoot":"","sources":["../../src/integrations/integration-campaign-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,GAC3C,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,2BAA2B,EAC3B,cAAc,GACf,MAAM,0BAA0B,CAAC;AASlC,SAAS,2BAA2B,CAAC,OAAe;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAGhC,CAAC;QACF,OAAO,CACL,MAAM,CAAC,IAAI,KAAK,mBAAmB;YACnC,MAAM,CAAC,eAAe,EAAE,MAAM,KAAK,WAAW,CAC/C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,OAIpD;IACC,MAAM,GAAG,GAAG,MAAM,6BAA6B,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACrE,MAAM,MAAM,GAAsC;QAChD,QAAQ,EAAE,GAAG,CAAC,MAAM;QACpB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;KACV,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC1C,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,sBAAsB,GAAG,0CAA0C,CACvE;gBACE,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,eAAe,EAAE,IAAI,CAAC,aAAa;oBACjC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE;oBACnC,CAAC,CAAC,SAAS;aACd,CACF,CAAC;YACF,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,CAAC,sBAAsB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACjD,MAAM,mCAAmC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAChD,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,gBAAgB,CACtB,CAAC;gBACF,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,8BAA8B,CAAC;wBACnC,MAAM,EAAE,QAAQ,CAAC,EAAE;wBACnB,IAAI,EAAE;4BACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;4BACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;4BACvC,eAAe,EAAE,QAAQ,CAAC,aAAa;gCACrC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE;gCACvC,CAAC,CAAC,SAAS;yBACd;wBACD,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,OAAO,EAAE,OAAO,CAAC,cAAc;qBAChC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,8BAA8B,CAAC;gBACnD,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,IAAI,EAAE;oBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;oBACvC,eAAe,EAAE,IAAI,CAAC,aAAa;wBACjC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE;wBACnC,CAAC,CAAC,SAAS;iBACd;gBACD,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,OAAO,EAAE,OAAO,CAAC,cAAc;gBAC/B,oBAAoB,EAAE,IAAI;gBAC1B,GAAG,CAAC,gBAAgB,IAAI,CAAC,sBAAsB;oBAC7C,CAAC,CAAC,EAAE,2CAA2C,EAAE,IAAI,EAAE;oBACvD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;YACH,IAAI,OAAO,KAAK,QAAQ;gBAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;;gBACxC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YACnB,OAAO,CAAC,KAAK,CACX,sDAAsD,EAAE,GAAG,EAC3D,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import {\n getIntegrationCampaign,\n failDisabledIntegrationCampaignTask,\n listDueIntegrationCampaignIds,\n} from \"./integration-campaigns-store.js\";\nimport {\n dispatchPendingIntegrationTask,\n isIntegrationDurableDispatchEnabledForTask,\n} from \"./integration-durable-dispatch.js\";\nimport {\n getNextPendingTaskForThread,\n getPendingTask,\n} from \"./pending-tasks-store.js\";\n\nexport interface IntegrationCampaignRecoveryResult {\n selected: number;\n dispatched: number;\n skipped: number;\n failed: number;\n}\n\nfunction hasConfirmedDeliveryReceipt(payload: string): boolean {\n try {\n const parsed = JSON.parse(payload) as {\n kind?: unknown;\n deliveryReceipt?: { status?: unknown };\n };\n return (\n parsed.kind === \"response-delivery\" &&\n parsed.deliveryReceipt?.status === \"delivered\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Wake due campaign chunks without claiming or executing them in the sweep.\n * The signed process-task endpoint owns the lease and all mutations.\n */\nexport async function recoverDueIntegrationCampaigns(options: {\n limit?: number;\n event?: unknown;\n webhookBaseUrl?: string;\n}): Promise<IntegrationCampaignRecoveryResult> {\n const ids = await listDueIntegrationCampaignIds(options.limit ?? 20);\n const result: IntegrationCampaignRecoveryResult = {\n selected: ids.length,\n dispatched: 0,\n skipped: 0,\n failed: 0,\n };\n\n for (const id of ids) {\n try {\n const campaign = await getIntegrationCampaign(id);\n if (!campaign) {\n result.skipped += 1;\n continue;\n }\n const task = await getPendingTask(campaign.integrationTaskId);\n if (!task || task.status !== \"processing\") {\n result.skipped += 1;\n continue;\n }\n const durableDispatchEnabled = isIntegrationDurableDispatchEnabledForTask(\n {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: task.dispatchScope\n ? { channelId: task.dispatchScope }\n : undefined,\n },\n );\n const confirmedReceipt = hasConfirmedDeliveryReceipt(task.payload);\n if (!durableDispatchEnabled && !confirmedReceipt) {\n await failDisabledIntegrationCampaignTask(task.id);\n const nextTask = await getNextPendingTaskForThread(\n task.platform,\n task.externalThreadId,\n );\n if (nextTask) {\n await dispatchPendingIntegrationTask({\n taskId: nextTask.id,\n task: {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: nextTask.dispatchScope\n ? { channelId: nextTask.dispatchScope }\n : undefined,\n },\n event: options.event,\n baseUrl: options.webhookBaseUrl,\n });\n }\n result.skipped += 1;\n continue;\n }\n const outcome = await dispatchPendingIntegrationTask({\n taskId: task.id,\n task: {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: task.dispatchScope\n ? { channelId: task.dispatchScope }\n : undefined,\n },\n event: options.event,\n baseUrl: options.webhookBaseUrl,\n campaignContinuation: true,\n ...(confirmedReceipt && !durableDispatchEnabled\n ? { allowPortableConfirmedReceiptReconciliation: true }\n : {}),\n });\n if (outcome === \"failed\") result.failed += 1;\n else result.dispatched += 1;\n } catch (error) {\n result.failed += 1;\n console.error(\n `[integrations] Failed to wake integration campaign ${id}:`,\n error,\n );\n }\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"integration-campaign-recovery.js","sourceRoot":"","sources":["../../src/integrations/integration-campaign-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { getA2AContinuationTaskOutcome } from \"./a2a-continuations-store.js\";\nimport {\n getIntegrationCampaign,\n failDisabledIntegrationCampaignTask,\n listDueIntegrationCampaignIds,\n} from \"./integration-campaigns-store.js\";\nimport {\n dispatchPendingIntegrationTask,\n isIntegrationDurableDispatchEnabledForTask,\n} from \"./integration-durable-dispatch.js\";\nimport {\n getNextPendingTaskForThread,\n getPendingTask,\n} from \"./pending-tasks-store.js\";\n\nexport interface IntegrationCampaignRecoveryResult {\n selected: number;\n dispatched: number;\n skipped: number;\n failed: number;\n}\n\nfunction hasConfirmedDeliveryReceipt(payload: string): boolean {\n try {\n const parsed = JSON.parse(payload) as {\n kind?: unknown;\n deliveryReceipt?: { status?: unknown };\n };\n return (\n parsed.kind === \"response-delivery\" &&\n parsed.deliveryReceipt?.status === \"delivered\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Wake due campaign chunks without claiming or executing them in the sweep.\n * The signed process-task endpoint owns the lease and all mutations.\n */\nexport async function recoverDueIntegrationCampaigns(options: {\n limit?: number;\n event?: unknown;\n webhookBaseUrl?: string;\n}): Promise<IntegrationCampaignRecoveryResult> {\n const ids = await listDueIntegrationCampaignIds(options.limit ?? 20);\n const result: IntegrationCampaignRecoveryResult = {\n selected: ids.length,\n dispatched: 0,\n skipped: 0,\n failed: 0,\n };\n\n for (const id of ids) {\n try {\n const campaign = await getIntegrationCampaign(id);\n if (!campaign) {\n result.skipped += 1;\n continue;\n }\n const task = await getPendingTask(campaign.integrationTaskId);\n if (!task || task.status !== \"processing\") {\n result.skipped += 1;\n continue;\n }\n const durableDispatchEnabled = isIntegrationDurableDispatchEnabledForTask(\n {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: task.dispatchScope\n ? { channelId: task.dispatchScope }\n : undefined,\n },\n );\n const confirmedReceipt =\n hasConfirmedDeliveryReceipt(task.payload) ||\n (await getA2AContinuationTaskOutcome(task.id)) === \"terminal-delivered\";\n if (!durableDispatchEnabled && !confirmedReceipt) {\n await failDisabledIntegrationCampaignTask(task.id);\n const nextTask = await getNextPendingTaskForThread(\n task.platform,\n task.externalThreadId,\n );\n if (nextTask) {\n await dispatchPendingIntegrationTask({\n taskId: nextTask.id,\n task: {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: nextTask.dispatchScope\n ? { channelId: nextTask.dispatchScope }\n : undefined,\n },\n event: options.event,\n baseUrl: options.webhookBaseUrl,\n });\n }\n result.skipped += 1;\n continue;\n }\n const outcome = await dispatchPendingIntegrationTask({\n taskId: task.id,\n task: {\n platform: task.platform,\n externalThreadId: task.externalThreadId,\n platformContext: task.dispatchScope\n ? { channelId: task.dispatchScope }\n : undefined,\n },\n event: options.event,\n baseUrl: options.webhookBaseUrl,\n campaignContinuation: true,\n ...(confirmedReceipt && !durableDispatchEnabled\n ? { allowPortableConfirmedReceiptReconciliation: true }\n : {}),\n });\n if (outcome === \"failed\") result.failed += 1;\n else result.dispatched += 1;\n } catch (error) {\n result.failed += 1;\n console.error(\n `[integrations] Failed to wake integration campaign ${id}:`,\n error,\n );\n }\n }\n\n return result;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/integrations/plugin.ts"],"names":[],"mappings":"AA6CA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA0HzD,OAAO,KAAK,EACV,eAAe,EACf,yBAAyB,EAK1B,MAAM,YAAY,CAAC;AAYpB,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAyM9D,eAAO,MAAM,sCAAsC;uBACrC,OAAO;;;uBACP,UAAU;;;uBACV,UAAU;;;uBACV,iBAAiB;;;uBACjB,SAAS;;;uBACT,aAAa;;;uBACb,OAAO;;EAIlB,CAAC;AAEJ,eAAO,MAAM,gCAAgC,0GAE5C,CAAC;AAEF,wBAAgB,gCAAgC,IAAI,eAAe,EAAE,CAEpE;AAUD,KAAK,yBAAyB,GAAG;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAgCF,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAsFlC;AAmOD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,yBAAyB,GAClC,cAAc,CAklFhB;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,gBAA6B,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/integrations/plugin.ts"],"names":[],"mappings":"AA4CA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA0HzD,OAAO,KAAK,EACV,eAAe,EACf,yBAAyB,EAK1B,MAAM,YAAY,CAAC;AAYpB,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAyM9D,eAAO,MAAM,sCAAsC;uBACrC,OAAO;;;uBACP,UAAU;;;uBACV,UAAU;;;uBACV,iBAAiB;;;uBACjB,SAAS;;;uBACT,aAAa;;;uBACb,OAAO;;EAIlB,CAAC;AAEJ,eAAO,MAAM,gCAAgC,0GAE5C,CAAC;AAEF,wBAAgB,gCAAgC,IAAI,eAAe,EAAE,CAEpE;AAUD,KAAK,yBAAyB,GAAG;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAgCF,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAsFlC;AAmOD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,yBAAyB,GAClC,cAAc,CAqmFhB;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,gBAA6B,CAAC"}
@@ -13,8 +13,8 @@ import { getH3App, markDefaultPluginProvided, } from "../server/framework-reques
13
13
  import { decodeOAuthState, encodeOAuthState, oauthCallbackResponse, oauthErrorPage, resolveOAuthRedirectUri, } from "../server/google-oauth.js";
14
14
  import { readBody } from "../server/h3-helpers.js";
15
15
  import { runWithRequestContext } from "../server/request-context.js";
16
- import { processA2AContinuationById, processDueA2AContinuations, recoverDueA2AContinuations, } from "./a2a-continuation-processor.js";
17
- import { failA2AContinuation, hasActiveA2AContinuationsForIntegrationTask, } from "./a2a-continuations-store.js";
16
+ import { processA2AContinuationById, processDueA2AContinuations, reconcileTerminalA2AParentIfDisabled, recoverA2AContinuationAfterProcessorFailure, recoverDueA2AContinuations, } from "./a2a-continuation-processor.js";
17
+ import { getA2AContinuationTaskOutcome } from "./a2a-continuations-store.js";
18
18
  import { mergeIntegrationAdapters } from "./adapter-overrides.js";
19
19
  import { discordAdapter } from "./adapters/discord.js";
20
20
  import { emailAdapter } from "./adapters/email.js";
@@ -1477,11 +1477,15 @@ export function createIntegrationsPlugin(options) {
1477
1477
  ? { channelId: task.dispatchScope }
1478
1478
  : undefined,
1479
1479
  });
1480
+ const a2aOutcome = campaignContinuation
1481
+ ? await getA2AContinuationTaskOutcome(task.id)
1482
+ : null;
1480
1483
  const confirmedDeliveryReceipt = taskPayload.kind === "response-delivery" &&
1481
1484
  taskPayload.deliveryReceipt?.status === "delivered";
1485
+ const confirmedDeliveryProof = confirmedDeliveryReceipt || a2aOutcome === "terminal-delivered";
1482
1486
  if (campaignContinuation &&
1483
1487
  !durableCampaignEnabled &&
1484
- !confirmedDeliveryReceipt) {
1488
+ !confirmedDeliveryProof) {
1485
1489
  await failDisabledIntegrationCampaignTask(task.id);
1486
1490
  const nextTask = await getNextPendingTaskForThread(task.platform, task.externalThreadId);
1487
1491
  if (nextTask) {
@@ -1535,6 +1539,14 @@ export function createIntegrationsPlugin(options) {
1535
1539
  return;
1536
1540
  }
1537
1541
  if (taskPayload.kind === "response-delivery") {
1542
+ if (campaignContinuation &&
1543
+ taskPayload.awaitingA2ACompletion &&
1544
+ a2aOutcome === "terminal-delivered") {
1545
+ const completed = await completeIntegrationCampaignTaskAfterA2A(task.id);
1546
+ return completed
1547
+ ? "completed"
1548
+ : "campaign-active";
1549
+ }
1538
1550
  let receipt = taskPayload.deliveryReceipt;
1539
1551
  let deliveryLease;
1540
1552
  if (campaignContinuation && !receipt) {
@@ -1626,11 +1638,12 @@ export function createIntegrationsPlugin(options) {
1626
1638
  if (!waiting)
1627
1639
  return "campaign-active";
1628
1640
  }
1629
- if (!(await hasActiveA2AContinuationsForIntegrationTask(task.id))) {
1630
- const completed = await completeIntegrationCampaignTaskAfterA2A(task.id);
1631
- return completed
1632
- ? "completed"
1633
- : "campaign-active";
1641
+ if (a2aOutcome === "terminal-without-delivery" &&
1642
+ (await reconcileTerminalA2AParentIfDisabled(task.id))) {
1643
+ return "campaign-failed";
1644
+ }
1645
+ if (a2aOutcome !== "active") {
1646
+ console.warn(`[integrations] Waiting campaign ${task.id} has A2A outcome ${a2aOutcome} without terminal delivery proof`);
1634
1647
  }
1635
1648
  return "campaign-active";
1636
1649
  }
@@ -1826,10 +1839,14 @@ export function createIntegrationsPlugin(options) {
1826
1839
  });
1827
1840
  }
1828
1841
  catch (err) {
1829
- // Mark the continuation failed so it isn't left dangling, and surface
1830
- // a 500 to the caller instead of leaking an unhandled rejection.
1831
- await failA2AContinuation(continuationId, err?.message?.slice(0, 500) || "continuation processing failed").catch(() => { });
1832
- console.error("[integrations] process-a2a-continuation failure:", err);
1842
+ const reason = err?.message?.slice(0, 500) || "continuation processing failed";
1843
+ await recoverA2AContinuationAfterProcessorFailure(continuationId, {
1844
+ adapters: adapterMap,
1845
+ reason,
1846
+ }).catch(() => {
1847
+ console.error(`[integrations] A2A continuation ${continuationId} recovery scheduling failed`);
1848
+ });
1849
+ console.error(`[integrations] process-a2a-continuation failure for ${continuationId}; durable recovery requested`);
1833
1850
  setResponseStatus(event, 500);
1834
1851
  return { error: "Failed to process A2A continuation" };
1835
1852
  }