@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":"a2a-continuations-store.js","sourceRoot":"","sources":["../../src/integrations/a2a-continuations-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n isPostgres,\n intType,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport {\n ensureTableExists,\n ensureColumnExists,\n ensureIndexExists,\n} from \"../db/ddl-guard.js\";\nimport { isDuplicateColumnError } from \"../db/migrations.js\";\nimport type { IncomingMessage, PlatformRunProgressRef } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\nconst PROCESSING_STUCK_AFTER_MS = 5 * 60 * 1000;\nconst PROCESSING_NEXT_CHECK_STALE_AFTER_MS = 60 * 1000;\n\n// Build the CREATE SQL lazily (not at module scope) so intType() runs at\n// RUNTIME, not import time — a module-scope call breaks any consumer whose\n// db/client mock doesn't stub intType (e.g. db-admin specs).\nfunction buildCreateSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_a2a_continuations (\n id TEXT PRIMARY KEY,\n integration_task_id TEXT NOT NULL,\n platform TEXT NOT NULL,\n external_thread_id TEXT NOT NULL,\n incoming_payload TEXT NOT NULL,\n placeholder_ref TEXT,\n progress_ref TEXT,\n progress_ref_claimed ${intType()} NOT NULL DEFAULT 0,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n agent_name TEXT NOT NULL,\n agent_url TEXT NOT NULL,\n dedupe_key TEXT,\n a2a_task_id TEXT NOT NULL,\n a2a_auth_token TEXT,\n status TEXT NOT NULL,\n attempts ${intType()} NOT NULL DEFAULT 0,\n next_check_at ${intType()} NOT NULL,\n error_message TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL,\n completed_at ${intType()}\n )\n`;\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = buildCreateSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_a2a_continuations\", createSql);\n await ensureIndexExists(\n \"idx_a2a_continuations_status_next\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_status_next ON integration_a2a_continuations(status, next_check_at)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_integration_task\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_integration_task ON integration_a2a_continuations(integration_task_id)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_remote_task\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"a2a_auth_token\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS a2a_auth_token TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"dedupe_key\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS dedupe_key TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"progress_ref\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"progress_ref_claimed\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref_claimed ${intType()} NOT NULL DEFAULT 0`,\n );\n await backfillProgressRefOwners(client);\n await ensureIndexExists(\n \"idx_a2a_continuations_dedupe_key\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_one_progress_owner\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_status_next ON integration_a2a_continuations(status, next_check_at)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_integration_task ON integration_a2a_continuations(integration_task_id)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`,\n ),\n );\n await addColumnIfMissing(\"a2a_auth_token\", \"TEXT\");\n await addColumnIfMissing(\"dedupe_key\", \"TEXT\");\n await addColumnIfMissing(\"progress_ref\", \"TEXT\");\n await addColumnIfMissing(\n \"progress_ref_claimed\",\n `${intType()} NOT NULL DEFAULT 0`,\n );\n await backfillProgressRefOwners(client);\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`,\n ),\n );\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nasync function addColumnIfMissing(name: string, definition: string) {\n try {\n await retryOnDdlRace(() =>\n getDbExec().execute(\n `ALTER TABLE integration_a2a_continuations ADD COLUMN ${name} ${definition}`,\n ),\n );\n } catch (err) {\n if (isDuplicateColumnError(err)) return;\n throw err;\n }\n}\n\nasync function backfillProgressRefOwners(\n client: ReturnType<typeof getDbExec>,\n): Promise<void> {\n await client.execute(`\n UPDATE integration_a2a_continuations AS candidate\n SET progress_ref_claimed = 1\n WHERE candidate.progress_ref IS NOT NULL\n AND candidate.status NOT IN ('completed', 'failed')\n AND candidate.progress_ref_claimed = 0\n AND NOT EXISTS (\n SELECT 1\n FROM integration_a2a_continuations AS owner\n WHERE owner.integration_task_id = candidate.integration_task_id\n AND owner.progress_ref_claimed = 1\n )\n AND candidate.id = (\n SELECT selected.id\n FROM integration_a2a_continuations AS selected\n WHERE selected.integration_task_id = candidate.integration_task_id\n AND selected.progress_ref IS NOT NULL\n AND selected.status NOT IN ('completed', 'failed')\n ORDER BY selected.created_at ASC, selected.id ASC\n LIMIT 1\n )\n `);\n}\n\nexport type A2AContinuationStatus =\n | \"pending\"\n | \"processing\"\n | \"delivering\"\n | \"completed\"\n | \"failed\";\n\nexport interface A2AContinuation {\n id: string;\n integrationTaskId: string;\n platform: string;\n externalThreadId: string;\n incoming: IncomingMessage;\n placeholderRef: string | null;\n progressRef: PlatformRunProgressRef | null;\n progressRefClaimed: boolean;\n ownerEmail: string;\n orgId: string | null;\n agentName: string;\n agentUrl: string;\n dedupeKey: string | null;\n a2aTaskId: string;\n a2aAuthToken: string | null;\n status: A2AContinuationStatus;\n attempts: number;\n nextCheckAt: number;\n errorMessage: string | null;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nconst MAX_PROGRESS_REF_KIND_CHARS = 128;\nconst MAX_PROGRESS_REF_STREAM_TS_CHARS = 256;\n\n/**\n * Keep only the tiny, adapter-owned continuation reference. Invalid rows are\n * treated as unavailable rather than throwing during a retry sweep.\n */\nfunction parseProgressRef(value: unknown): PlatformRunProgressRef | null {\n if (typeof value !== \"string\" || value.length === 0) return null;\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const { kind, streamTs } = parsed as Record<string, unknown>;\n if (\n typeof kind !== \"string\" ||\n typeof streamTs !== \"string\" ||\n kind.length === 0 ||\n streamTs.length === 0 ||\n kind.length > MAX_PROGRESS_REF_KIND_CHARS ||\n streamTs.length > MAX_PROGRESS_REF_STREAM_TS_CHARS\n ) {\n return null;\n }\n return { kind, streamTs };\n } catch {\n return null;\n }\n}\n\nfunction serializeProgressRef(value: unknown): string | null {\n const parsed = parseProgressRef(\n typeof value === \"string\" ? value : JSON.stringify(value),\n );\n return parsed ? JSON.stringify(parsed) : null;\n}\n\nfunction rowToContinuation(row: Record<string, unknown>): A2AContinuation {\n return {\n id: row.id as string,\n integrationTaskId: row.integration_task_id as string,\n platform: row.platform as string,\n externalThreadId: row.external_thread_id as string,\n incoming: JSON.parse(row.incoming_payload as string) as IncomingMessage,\n placeholderRef: (row.placeholder_ref as string | null) ?? null,\n progressRef: parseProgressRef(row.progress_ref),\n progressRefClaimed: Number(row.progress_ref_claimed ?? 0) === 1,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n agentName: row.agent_name as string,\n agentUrl: row.agent_url as string,\n dedupeKey: (row.dedupe_key as string | null) ?? null,\n a2aTaskId: row.a2a_task_id as string,\n a2aAuthToken: (row.a2a_auth_token as string | null) ?? null,\n status: row.status as A2AContinuationStatus,\n attempts: Number(row.attempts ?? 0),\n nextCheckAt: Number(row.next_check_at ?? 0),\n errorMessage: (row.error_message as string | null) ?? null,\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n completedAt:\n row.completed_at == null ? null : Number(row.completed_at as number),\n };\n}\n\nexport async function insertA2AContinuation(input: {\n integrationTaskId: string;\n platform: string;\n externalThreadId: string;\n incoming: IncomingMessage;\n placeholderRef?: string | null;\n progressRef?: PlatformRunProgressRef | null;\n ownerEmail: string;\n orgId?: string | null;\n agentName: string;\n agentUrl: string;\n dedupeKey?: string | null;\n a2aTaskId: string;\n a2aAuthToken?: string | null;\n}): Promise<A2AContinuation> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const id = `a2a-cont-${now}-${Math.random().toString(36).slice(2, 8)}`;\n const payload = JSON.stringify(input.incoming);\n const progressRef = serializeProgressRef(input.progressRef);\n\n try {\n await client.execute({\n sql: `INSERT INTO integration_a2a_continuations\n (id, integration_task_id, platform, external_thread_id, incoming_payload,\n placeholder_ref, progress_ref, progress_ref_claimed, owner_email, org_id, agent_name, agent_url, dedupe_key, a2a_task_id, a2a_auth_token,\n status, attempts, next_check_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.integrationTaskId,\n input.platform,\n input.externalThreadId,\n payload,\n input.placeholderRef ?? null,\n null,\n 0,\n input.ownerEmail,\n input.orgId ?? null,\n input.agentName,\n input.agentUrl,\n input.dedupeKey ?? null,\n input.a2aTaskId,\n input.a2aAuthToken ?? null,\n \"pending\",\n 0,\n now,\n now,\n now,\n ],\n });\n } catch (err: any) {\n if (!isDuplicateContinuationError(err)) throw err;\n const existing = await findA2AContinuation(\n input.integrationTaskId,\n input.agentUrl,\n input.a2aTaskId,\n );\n if (existing) {\n // A retry can reach this row after the original invocation created it\n // without a resumable progress surface (or with one that has gone\n // stale). Keep the most recent valid adapter reference for active work,\n // but never resurrect short-lived delivery state after a terminal row\n // has deliberately scrubbed it.\n if (\n progressRef &&\n existing.status !== \"completed\" &&\n existing.status !== \"failed\"\n ) {\n if (existing.progressRefClaimed) {\n if (JSON.stringify(existing.progressRef) !== progressRef) {\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET progress_ref = ?, updated_at = ?\n WHERE id = ? AND status NOT IN ('completed', 'failed')\n AND progress_ref_claimed = 1\n AND (progress_ref IS NULL OR progress_ref <> ?)`,\n args: [progressRef, now, existing.id, progressRef],\n });\n }\n } else {\n await claimA2AContinuationProgressRef(existing.id, progressRef);\n }\n return (await getA2AContinuation(existing.id)) ?? existing;\n }\n return existing;\n }\n throw err;\n }\n\n if (progressRef) {\n await claimA2AContinuationProgressRef(id, progressRef);\n }\n return (await getA2AContinuation(id))!;\n}\n\n/**\n * A native platform stream has one terminal completion. Claim it for a single\n * downstream continuation, and retain the ownership marker after terminal\n * cleanup scrubs the short-lived stream reference. The partial unique index\n * makes concurrent downstream inserts safe across processes.\n */\nasync function claimA2AContinuationProgressRef(\n id: string,\n progressRef: string,\n): Promise<void> {\n try {\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET progress_ref = ?, progress_ref_claimed = 1\n WHERE id = ? AND progress_ref_claimed = 0`,\n args: [progressRef, id],\n });\n } catch (err) {\n // A sibling continuation already owns this stream and will finalize it.\n // This continuation still delivers through the normal response path.\n if (isDuplicateContinuationError(err)) return;\n throw err;\n }\n}\n\nexport async function getA2AContinuationForIntegrationTask(\n integrationTaskId: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ?\n ORDER BY created_at ASC\n LIMIT 1`,\n args: [integrationTaskId],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function hasActiveA2AContinuationsForIntegrationTask(\n integrationTaskId: string,\n): Promise<boolean> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT 1 AS active FROM integration_a2a_continuations\n WHERE integration_task_id = ?\n AND status IN ('pending', 'processing', 'delivering')\n LIMIT 1`,\n args: [integrationTaskId],\n });\n return rows.length > 0;\n}\n\nexport async function failA2AContinuationsForIntegrationTask(\n integrationTaskId: string,\n errorMessage: string,\n): Promise<void> {\n await ensureTable();\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = 'failed', error_message = ?, updated_at = ?, completed_at = ?\n WHERE integration_task_id = ?\n AND status IN ('pending', 'processing', 'delivering')`,\n args: [errorMessage.slice(0, 2000), now, now, integrationTaskId],\n });\n}\n\nexport async function getA2AContinuationsForIntegrationTaskAgent(\n integrationTaskId: string,\n agentUrl: string,\n dedupeKey?: string | null,\n): Promise<A2AContinuation[]> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute(\n dedupeKey\n ? {\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ? AND dedupe_key = ?\n ORDER BY created_at ASC`,\n args: [integrationTaskId, agentUrl, dedupeKey],\n }\n : {\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ?\n ORDER BY created_at ASC`,\n args: [integrationTaskId, agentUrl],\n },\n );\n return rows.map((row) => rowToContinuation(row as Record<string, unknown>));\n}\n\nfunction isDuplicateContinuationError(err: unknown): boolean {\n const e = err as { code?: string; message?: string } | null;\n if (!e) return false;\n if (e.code === \"23505\") return true;\n const msg = String(e.message ?? \"\").toLowerCase();\n return (\n msg.includes(\"unique\") ||\n msg.includes(\"duplicate entry\") ||\n msg.includes(\"duplicate key\")\n );\n}\n\nasync function findA2AContinuation(\n integrationTaskId: string,\n agentUrl: string,\n a2aTaskId: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ? AND a2a_task_id = ?\n LIMIT 1`,\n args: [integrationTaskId, agentUrl, a2aTaskId],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function getA2AContinuation(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations WHERE id = ? LIMIT 1`,\n args: [id],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function claimA2AContinuation(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const processingCutoff = now - PROCESSING_STUCK_AFTER_MS;\n const staleNextCheckCutoff = now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS;\n const result = await client.execute({\n sql: isPostgres()\n ? `UPDATE integration_a2a_continuations\n SET status = ?, attempts = attempts + 1, updated_at = ?\n WHERE id = ?\n AND (\n status = 'pending'\n OR (\n status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)\n )\n )\n RETURNING *`\n : `UPDATE integration_a2a_continuations\n SET status = ?, attempts = attempts + 1, updated_at = ?\n WHERE id = ?\n AND (\n status = 'pending'\n OR (\n status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)\n )\n )`,\n args: [\"processing\", now, id, processingCutoff, staleNextCheckCutoff],\n });\n const rows = result.rows ?? [];\n if (isPostgres()) {\n return rows[0]\n ? rowToContinuation(rows[0] as Record<string, unknown>)\n : null;\n }\n const affected = (result as any)?.rowsAffected ?? (result as any)?.rowCount;\n if (affected === 0) return null;\n const fetched = await getA2AContinuation(id);\n if (!fetched || fetched.status !== \"processing\") return null;\n return fetched;\n}\n\nexport async function claimDueA2AContinuations(\n limit = 5,\n): Promise<A2AContinuation[]> {\n const ids = await recoverDueA2AContinuationIds(limit);\n const claimed: A2AContinuation[] = [];\n for (const id of ids) {\n const continuation = await claimA2AContinuation(id);\n if (continuation) claimed.push(continuation);\n }\n return claimed;\n}\n\n/**\n * Makes stale leases eligible again and returns a bounded set of due ids.\n *\n * This intentionally does not claim anything. Durable schedulers use it only\n * to wake the normal processor, whose atomic claim remains the sole progress\n * and delivery owner under overlapping scheduler/self-dispatch executions.\n */\nexport async function recoverDueA2AContinuationIds(\n limit = 5,\n integrationTaskIds?: string[],\n): Promise<string[]> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const processingCutoff = now - PROCESSING_STUCK_AFTER_MS;\n const staleNextCheckCutoff = now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS;\n if (integrationTaskIds && integrationTaskIds.length === 0) return [];\n const taskFilter = integrationTaskIds?.length\n ? ` AND integration_task_id IN (${integrationTaskIds.map(() => \"?\").join(\", \")})`\n : \"\";\n const taskArgs = integrationTaskIds ?? [];\n // If a processor dies while holding a delivery claim, retry the final send.\n // The stale cutoff preserves the in-flight delivery guard while keeping\n // final integration replies at-least-once.\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE status = 'delivering' AND updated_at <= ?${taskFilter}`,\n args: [\"pending\", now, now, now - 5 * 60 * 1000, ...taskArgs],\n });\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)${taskFilter}`,\n args: [\n \"pending\",\n now,\n now,\n processingCutoff,\n staleNextCheckCutoff,\n ...taskArgs,\n ],\n });\n const { rows } = await client.execute({\n sql: `SELECT id FROM integration_a2a_continuations\n WHERE status = 'pending' AND next_check_at <= ?${taskFilter}\n ORDER BY next_check_at ASC\n LIMIT ?`,\n args: [now, ...taskArgs, limit],\n });\n return rows.map((row) => row.id as string);\n}\n\nexport async function listRecoverableA2AIntegrationTaskIds(\n limit = 50,\n): Promise<string[]> {\n const tasks = await listRecoverableA2AIntegrationTasks(limit);\n return tasks.map((task) => task.id);\n}\n\nexport interface RecoverableA2AIntegrationTask {\n id: string;\n platform: string;\n externalThreadId: string;\n dispatchScope: string | null;\n status: string;\n}\n\n/**\n * Read due continuation owners and their rollout scope in one query. Recovery\n * can filter the canary in memory without an N+1 pending-task lookup loop.\n */\nexport async function listRecoverableA2AIntegrationTasks(\n limit = 50,\n): Promise<RecoverableA2AIntegrationTask[]> {\n await ensureTable();\n const now = Date.now();\n const { rows } = await getDbExec().execute({\n sql: `SELECT DISTINCT c.integration_task_id, t.platform,\n t.external_thread_id, t.dispatch_scope, t.status\n FROM integration_a2a_continuations c\n INNER JOIN integration_pending_tasks t\n ON t.id = c.integration_task_id\n WHERE t.status = 'processing'\n AND ((c.status = 'pending' AND c.next_check_at <= ?)\n OR (c.status = 'processing' AND\n (c.updated_at <= ? OR c.next_check_at <= ?))\n OR (c.status = 'delivering' AND c.updated_at <= ?))\n ORDER BY c.integration_task_id ASC\n LIMIT ?`,\n args: [\n now,\n now - PROCESSING_STUCK_AFTER_MS,\n now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS,\n now - 5 * 60 * 1000,\n Math.max(1, Math.min(Math.floor(limit), 200)),\n ],\n });\n return rows.map((row) => ({\n id: String(row.integration_task_id),\n platform: String(row.platform),\n externalThreadId: String(row.external_thread_id),\n dispatchScope: (row.dispatch_scope as string | null) ?? null,\n status: String(row.status),\n }));\n}\n\nexport async function claimA2AContinuationDelivery(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: isPostgres()\n ? `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?\n WHERE id = ? AND status = 'processing'\n RETURNING *`\n : `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?\n WHERE id = ? AND status = 'processing'`,\n args: [\"delivering\", now, id],\n });\n const rows = result.rows ?? [];\n if (isPostgres()) {\n return rows[0]\n ? rowToContinuation(rows[0] as Record<string, unknown>)\n : null;\n }\n const affected = (result as any)?.rowsAffected ?? (result as any)?.rowCount;\n if (affected === 0) return null;\n const fetched = await getA2AContinuation(id);\n if (!fetched || fetched.status !== \"delivering\") return null;\n return fetched;\n}\n\nexport async function rescheduleA2AContinuation(\n id: string,\n delayMs: number,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE id = ? AND status IN ('processing', 'delivering')`,\n args: [\"pending\", now + delayMs, now, id],\n });\n}\n\nexport async function completeA2AContinuation(id: string): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?, completed_at = ?,\n incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL\n WHERE id = ? AND status IN ('processing', 'delivering', 'completed')`,\n args: [\"completed\", now, now, \"{}\", id],\n });\n}\n\nexport async function failA2AContinuation(\n id: string,\n errorMessage: string,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?, error_message = ?,\n incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL\n WHERE id = ? AND status <> 'completed'`,\n args: [\"failed\", now, errorMessage.slice(0, 2000), \"{}\", id],\n });\n}\n"]}
1
+ {"version":3,"file":"a2a-continuations-store.js","sourceRoot":"","sources":["../../src/integrations/a2a-continuations-store.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,IAAI,YAAuC,CAAC;AAC5C,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAChD,MAAM,oCAAoC,GAAG,EAAE,GAAG,IAAI,CAAC;AACvD,MAAM,sCAAsC,GAAG,EAAE,GAAG,IAAI,CAAC;AACzD,MAAM,sCAAsC,GAAG,MAAM,CAAC;AACtD,MAAM,kCAAkC,GAAG,MAAM,CAAC;AAElD,yEAAyE;AACzE,2EAA2E;AAC3E,6DAA6D;AAC7D,SAAS,cAAc;IACrB,OAAO;;;;;;;;;2BASkB,OAAO,EAAE;;;;;;;;;;qCAUC,OAAO,EAAE;;;eAG/B,OAAO,EAAE;oBACJ,OAAO,EAAE;;iBAEZ,OAAO,EAAE;iBACT,OAAO,EAAE;mBACP,OAAO,EAAE;;CAE3B,CAAC;AACF,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC;YACnC,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,0FAA0F;gBAC1F,MAAM,iBAAiB,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;gBACpE,MAAM,iBAAiB,CACrB,mCAAmC,EACnC,sHAAsH,CACvH,CAAC;gBACF,MAAM,iBAAiB,CACrB,wCAAwC,EACxC,yHAAyH,CAC1H,CAAC;gBACF,MAAM,iBAAiB,CACrB,mCAAmC,EACnC,mJAAmJ,CACpJ,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,gBAAgB,EAChB,wFAAwF,CACzF,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,YAAY,EACZ,oFAAoF,CACrF,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,cAAc,EACd,sFAAsF,CACvF,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,sBAAsB,EACtB,2FAA2F,OAAO,EAAE,qBAAqB,CAC1H,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,8BAA8B,EAC9B,sGAAsG,CACvG,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,wBAAwB,EACxB,gGAAgG,CACjG,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,gCAAgC,EAChC,qGAAqG,OAAO,EAAE,EAAE,CACjH,CAAC;gBACF,MAAM,kBAAkB,CACtB,+BAA+B,EAC/B,0BAA0B,EAC1B,kGAAkG,CACnG,CAAC;gBACF,MAAM,iCAAiC,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,yBAAyB,CAAC,MAAM,CAAC,CAAC;gBACxC,MAAM,iBAAiB,CACrB,kCAAkC,EAClC,0IAA0I,CAC3I,CAAC;gBACF,MAAM,iBAAiB,CACrB,0CAA0C,EAC1C,iKAAiK,CAClK,CAAC;gBACF,OAAO;YACT,CAAC;YACD,6CAA6C;YAC7C,MAAM,cAAc,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YACtD,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,sHAAsH,CACvH,CACF,CAAC;YACF,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,yHAAyH,CAC1H,CACF,CAAC;YACF,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,mJAAmJ,CACpJ,CACF,CAAC;YACF,MAAM,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YACjD,MAAM,kBAAkB,CACtB,sBAAsB,EACtB,GAAG,OAAO,EAAE,qBAAqB,CAClC,CAAC;YACF,MAAM,kBAAkB,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;YACjE,MAAM,kBAAkB,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;YAC3D,MAAM,kBAAkB,CAAC,gCAAgC,EAAE,OAAO,EAAE,CAAC,CAAC;YACtE,MAAM,kBAAkB,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC;YAC7D,MAAM,iCAAiC,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,yBAAyB,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,0IAA0I,CAC3I,CACF,CAAC;YACF,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,iKAAiK,CAClK,CACF,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjB,sDAAsD;YACtD,YAAY,GAAG,SAAS,CAAC;YACzB,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAC/C,MAAM,WAAW,EAAE,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,UAAkB;IAChE,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,GAAG,EAAE,CACxB,SAAS,EAAE,CAAC,OAAO,CACjB,wDAAwD,IAAI,IAAI,UAAU,EAAE,CAC7E,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,sBAAsB,CAAC,GAAG,CAAC;YAAE,OAAO;QACxC,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,MAAoC;IAEpC,MAAM,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;GAqBpB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,iCAAiC,CAC9C,MAAoC;IAEpC,MAAM,MAAM,CAAC,OAAO,CAAC;;;;;;GAMpB,CAAC,CAAC;AACL,CAAC;AAqDD,MAAM,2BAA2B,GAAG,GAAG,CAAC;AACxC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AAE7C;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAY,CAAC;QAC5C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAiC,CAAC;QAC7D,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,OAAO,QAAQ,KAAK,QAAQ;YAC5B,IAAI,CAAC,MAAM,KAAK,CAAC;YACjB,QAAQ,CAAC,MAAM,KAAK,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,2BAA2B;YACzC,QAAQ,CAAC,MAAM,GAAG,gCAAgC,EAClD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,MAAM,MAAM,GAAG,gBAAgB,CAC7B,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAC1D,CAAC;IACF,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,SAAS,iBAAiB,CAAC,GAA4B;IACrD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAY;QACpB,iBAAiB,EAAE,GAAG,CAAC,mBAA6B;QACpD,QAAQ,EAAE,GAAG,CAAC,QAAkB;QAChC,gBAAgB,EAAE,GAAG,CAAC,kBAA4B;QAClD,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAA0B,CAAoB;QACvE,cAAc,EAAG,GAAG,CAAC,eAAiC,IAAI,IAAI;QAC9D,WAAW,EAAE,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC;QAC/C,kBAAkB,EAAE,MAAM,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,CAAC,KAAK,CAAC;QAC/D,UAAU,EAAE,GAAG,CAAC,WAAqB;QACrC,KAAK,EAAG,GAAG,CAAC,MAAwB,IAAI,IAAI;QAC5C,SAAS,EAAE,GAAG,CAAC,UAAoB;QACnC,QAAQ,EAAE,GAAG,CAAC,SAAmB;QACjC,SAAS,EAAG,GAAG,CAAC,UAA4B,IAAI,IAAI;QACpD,SAAS,EAAE,GAAG,CAAC,WAAqB;QACpC,YAAY,EAAG,GAAG,CAAC,cAAgC,IAAI,IAAI;QAC3D,0BAA0B,EACvB,GAAG,CAAC,4BAA8C,IAAI,IAAI;QAC7D,oBAAoB,EAClB,GAAG,CAAC,sBAAsB,KAAK,SAAS;YACxC,GAAG,CAAC,sBAAsB,KAAK,SAAS;YACtC,CAAC,CAAC,GAAG,CAAC,sBAAsB;YAC5B,CAAC,CAAC,IAAI;QACV,2BAA2B,EACzB,GAAG,CAAC,8BAA8B,IAAI,IAAI;YACxC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;QAChD,sBAAsB,EAAE,2BAA2B,CACjD,GAAG,CAAC,wBAAwB,CAC7B;QACD,MAAM,EAAE,GAAG,CAAC,MAA+B;QAC3C,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC;QAC3C,YAAY,EAAG,GAAG,CAAC,aAA+B,IAAI,IAAI;QAC1D,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;QACtC,WAAW,EACT,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,YAAsB,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAClC,KAAc;IAEd,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAuC,CAAC;QACvE,IACE,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;YAC/B,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;YACtC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;YAClC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC;YAC3D,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAChC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAChC,CAAC,QAAQ,EAAmC,EAAE,CAC5C,CAAC,CAAC,QAAQ;gBACV,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACxB,OAAQ,QAA6B,CAAC,EAAE,KAAK,QAAQ;gBACrD,OAAQ,QAAuC,CAAC,YAAY;oBAC1D,QAAQ;gBACV,OAAQ,QAAuC,CAAC,YAAY;oBAC1D,QAAQ,CACb;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAc3C;IACC,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC;YACnB,GAAG,EAAE;;;;4EAIiE;YACtE,IAAI,EAAE;gBACJ,EAAE;gBACF,KAAK,CAAC,iBAAiB;gBACvB,KAAK,CAAC,QAAQ;gBACd,KAAK,CAAC,gBAAgB;gBACtB,OAAO;gBACP,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,IAAI;gBACJ,CAAC;gBACD,KAAK,CAAC,UAAU;gBAChB,KAAK,CAAC,KAAK,IAAI,IAAI;gBACnB,KAAK,CAAC,SAAS;gBACf,KAAK,CAAC,QAAQ;gBACd,KAAK,CAAC,SAAS,IAAI,IAAI;gBACvB,KAAK,CAAC,SAAS;gBACf,KAAK,CAAC,YAAY,IAAI,IAAI;gBAC1B,SAAS;gBACT,CAAC;gBACD,GAAG;gBACH,GAAG;gBACH,GAAG;aACJ;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC;YAAE,MAAM,GAAG,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CACxC,KAAK,CAAC,iBAAiB,EACvB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,SAAS,CAChB,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,sEAAsE;YACtE,kEAAkE;YAClE,wEAAwE;YACxE,sEAAsE;YACtE,gCAAgC;YAChC,IACE,WAAW;gBACX,QAAQ,CAAC,MAAM,KAAK,WAAW;gBAC/B,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAC5B,CAAC;gBACD,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;oBAChC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,WAAW,EAAE,CAAC;wBACzD,MAAM,MAAM,CAAC,OAAO,CAAC;4BACnB,GAAG,EAAE;;;;sEAImD;4BACxD,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC;yBACnD,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,+BAA+B,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;gBAClE,CAAC;gBACD,OAAO,CAAC,MAAM,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC;YAC7D,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,+BAA+B,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAE,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,+BAA+B,CAC5C,EAAU,EACV,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;YACxB,GAAG,EAAE;;sDAE2C;YAChD,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;SACxB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,qEAAqE;QACrE,IAAI,4BAA4B,CAAC,GAAG,CAAC;YAAE,OAAO;QAC9C,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,iBAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QACpC,GAAG,EAAE;;;kBAGS;QACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAA4B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2CAA2C,CAC/D,iBAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACzC,GAAG,EAAE;;;kBAGS;QACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,iBAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACzC,GAAG,EAAE;;wCAE+B;QACpC,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IACE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAChB,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CACrE,EACD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,8BAA8B,IAAI,IAAI,CAAC;QACpE,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,2BAA2B,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gDAAgD,CACpE,iBAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACzC,GAAG,EAAE;;;;kBAIS;QACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qDAAqD,CACzE,iBAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACzC,GAAG,EAAE;;;wCAG+B;QACpC,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC,CAAC;IACH,OAAO,CACL,IAAI,CAAC,MAAM,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,CACR,CAAC,GAAG,EAAE,EAAE,CACN,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ;YAC/B,GAAG,CAAC,sBAAsB,IAAI,IAAI;YAClC,GAAG,CAAC,8BAA8B,IAAI,IAAI;YAC1C,GAAG,CAAC,wBAAwB,IAAI,IAAI,CACvC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAC1D,iBAAyB,EACzB,YAAoB;IAEpB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACxB,GAAG,EAAE;;;;;uDAK8C;QACnD,IAAI,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,iBAAiB,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAC9D,iBAAyB,EACzB,QAAgB,EAChB,SAAyB;IAEzB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,SAAS;QACP,CAAC,CAAC;YACE,GAAG,EAAE;;wCAEyB;YAC9B,IAAI,EAAE,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,CAAC;SAC/C;QACH,CAAC,CAAC;YACE,GAAG,EAAE;;wCAEyB;YAC9B,IAAI,EAAE,CAAC,iBAAiB,EAAE,QAAQ,CAAC;SACpC,CACN,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAA8B,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,4BAA4B,CAAC,GAAY;IAChD,MAAM,CAAC,GAAG,GAAiD,CAAC;IAC5D,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,OAAO,CACL,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACtB,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC/B,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAC9B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,iBAAyB,EACzB,QAAgB,EAChB,SAAiB;IAEjB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QACpC,GAAG,EAAE;;kBAES;QACd,IAAI,EAAE,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,CAAC;KAC/C,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAA4B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAU;IAEV,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QACpC,GAAG,EAAE,kEAAkE;QACvE,IAAI,EAAE,CAAC,EAAE,CAAC;KACX,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAA4B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAU;IAEV,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,gBAAgB,GAAG,GAAG,GAAG,yBAAyB,CAAC;IACzD,MAAM,oBAAoB,GAAG,GAAG,GAAG,oCAAoC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAClC,GAAG,EAAE,UAAU,EAAE;YACf,CAAC,CAAC;;;;;;;;;;qBAUa;YACf,CAAC,CAAC;;;;;;;;;aASK;QACT,IAAI,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,gBAAgB,EAAE,oBAAoB,CAAC;KACtE,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/B,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,CAAC,CAAC;YACZ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAA4B,CAAC;YACvD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAI,MAAc,EAAE,YAAY,IAAK,MAAc,EAAE,QAAQ,CAAC;IAC5E,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAK,GAAG,CAAC;IAET,MAAM,GAAG,GAAG,MAAM,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACpD,IAAI,YAAY;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,KAAK,GAAG,CAAC,EACT,kBAA6B,EAC7B,qBAAqB,GAAG,KAAK;IAE7B,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,gBAAgB,GAAG,GAAG,GAAG,yBAAyB,CAAC;IACzD,MAAM,oBAAoB,GAAG,GAAG,GAAG,oCAAoC,CAAC;IACxE,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrE,MAAM,UAAU,GAAG,kBAAkB,EAAE,MAAM;QAC3C,CAAC,CAAC,gCAAgC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACjF,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,QAAQ,GAAG,kBAAkB,IAAI,EAAE,CAAC;IAC1C,MAAM,aAAa,GAAG,qBAAqB;QACzC,CAAC,CAAC,iDAAiD;QACnD,CAAC,CAAC,EAAE,CAAC;IACP,2EAA2E;IAC3E,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE;;;;mCAI0B,UAAU,GAAG,aAAa,EAAE;QAC3D,IAAI,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC;KACnE,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE;;;yDAGgD,UAAU,GAAG,aAAa,EAAE;QACjF,IAAI,EAAE;YACJ,SAAS;YACT,GAAG;YACH,GAAG;YACH,gBAAgB;YAChB,oBAAoB;YACpB,GAAG,QAAQ;SACZ;KACF,CAAC,CAAC;IACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QACpC,GAAG,EAAE;2DACkD,UAAU,GAAG,aAAa;;kBAEnE;QACd,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,KAAK,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAY,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,KAAK,GAAG,EAAE;IAEV,MAAM,KAAK,GAAG,MAAM,kCAAkC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAWD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,KAAK,GAAG,EAAE;IAEV,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACzC,GAAG,EAAE;;;;;;;;;;;;;;;;;;;kBAmBS;QACd,IAAI,EAAE;YACJ,GAAG;YACH,GAAG,GAAG,yBAAyB;YAC/B,GAAG,GAAG,oCAAoC;YAC1C,GAAG;YACH,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;YACnB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;SAC9C;KACF,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACnC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC9B,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAChD,aAAa,EAAG,GAAG,CAAC,cAAgC,IAAI,IAAI;QAC5D,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC1B,2BAA2B,EACzB,GAAG,CAAC,8BAA8B,KAAK,IAAI;YAC3C,MAAM,CAAC,GAAG,CAAC,8BAA8B,IAAI,CAAC,CAAC,KAAK,CAAC;KACxD,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,EAAU;IAEV,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAClC,GAAG,EAAE,UAAU,EAAE;YACf,CAAC,CAAC;;;qBAGa;YACf,CAAC,CAAC;;gDAEwC;QAC5C,IAAI,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/B,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,CAAC,CAAC;YACZ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAA4B,CAAC;YACvD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAI,MAAc,EAAE,YAAY,IAAK,MAAc,EAAE,QAAQ,CAAC;IAC5E,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,EAAU,EACV,OAAe;IAEf,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE;;kEAEyD;QAC9D,IAAI,EAAE,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;KAC1C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,EAAU;IAEV,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACxB,GAAG,EAAE;;;uDAG8C;QACnD,IAAI,EAAE,CAAC,GAAG,GAAG,yBAAyB,EAAE,GAAG,EAAE,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,EAAU,EACV,UAAkB;IAElB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,MAAM,GAAG,sCAAsC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CACb,wCAAwC,sCAAsC,aAAa,CAC5F,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACxB,GAAG,EAAE;;6EAEoE;QACzE,IAAI,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC/C,OAAO,SAAS,EAAE,0BAA0B,KAAK,UAAU;QACzD,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,EAAU,EACV,IAA6B,EAC7B,cAAyC,EACzC,YAAqB;IAErB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,iBAAiB,CAAC,MAAM,GAAG,kCAAkC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CACb,wCAAwC,kCAAkC,aAAa,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACxB,GAAG,EAAE;;;;;;;;6CAQoC;QACzC,IAAI,EAAE;YACJ,IAAI;YACJ,GAAG;YACH,iBAAiB;YACjB,GAAG,GAAG,sCAAsC;YAC5C,GAAG;YACH,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI;YACpC,EAAE;YACF,IAAI;SACL;KACF,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC/C,IACE,SAAS,EAAE,MAAM,KAAK,YAAY;QAClC,SAAS,CAAC,oBAAoB,KAAK,IAAI;QACvC,SAAS,CAAC,2BAA2B,IAAI,IAAI;QAC7C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC,KAAK,iBAAiB,EACtE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAAU;IACzD,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAClD,IACE,YAAY;QACZ,CAAC,YAAY,CAAC,MAAM,KAAK,WAAW,IAAI,YAAY,CAAC,MAAM,KAAK,QAAQ,CAAC;QACzE,YAAY,CAAC,2BAA2B,IAAI,IAAI;QAChD,YAAY,CAAC,sBAAsB,IAAI,IAAI,EAC3C,CAAC;QACD,OAAO;IACT,CAAC;IACD,IACE,CAAC,YAAY,EAAE,oBAAoB;QACnC,YAAY,CAAC,2BAA2B,IAAI,IAAI;QAChD,CAAC,YAAY,CAAC,sBAAsB,EACpC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GACV,YAAY,CAAC,oBAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3E,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC;QACxB,GAAG,EAAE;;;;;2DAKkD;QACvD,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;KACnC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC/C,IACE,SAAS,EAAE,MAAM,KAAK,MAAM;QAC5B,SAAS,CAAC,sBAAsB,IAAI,IAAI,EACxC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAAU;IACtD,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE;;;;;;;+EAOsE;QAC3E,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAU,EACV,YAAoB;IAEpB,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE;;;;iDAIwC;QAC7C,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;KAC7D,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { A2AArtifactIdentity } from \"../a2a/artifact-response.js\";\nimport {\n getDbExec,\n isPostgres,\n intType,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport {\n ensureTableExists,\n ensureColumnExists,\n ensureIndexExists,\n} from \"../db/ddl-guard.js\";\nimport { isDuplicateColumnError } from \"../db/migrations.js\";\nimport type { IncomingMessage, PlatformRunProgressRef } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\nconst PROCESSING_STUCK_AFTER_MS = 5 * 60 * 1000;\nconst PROCESSING_NEXT_CHECK_STALE_AFTER_MS = 60 * 1000;\nconst TERMINAL_HISTORY_FINALIZATION_LEASE_MS = 60 * 1000;\nconst MAX_VERIFIED_ARTIFACT_CHECKPOINT_CHARS = 16_000;\nconst MAX_TERMINAL_HISTORY_PAYLOAD_CHARS = 64_000;\n\n// Build the CREATE SQL lazily (not at module scope) so intType() runs at\n// RUNTIME, not import time — a module-scope call breaks any consumer whose\n// db/client mock doesn't stub intType (e.g. db-admin specs).\nfunction buildCreateSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_a2a_continuations (\n id TEXT PRIMARY KEY,\n integration_task_id TEXT NOT NULL,\n platform TEXT NOT NULL,\n external_thread_id TEXT NOT NULL,\n incoming_payload TEXT NOT NULL,\n placeholder_ref TEXT,\n progress_ref TEXT,\n progress_ref_claimed ${intType()} NOT NULL DEFAULT 0,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n agent_name TEXT NOT NULL,\n agent_url TEXT NOT NULL,\n dedupe_key TEXT,\n a2a_task_id TEXT NOT NULL,\n a2a_auth_token TEXT,\n verified_artifact_checkpoint TEXT,\n terminal_delivery_kind TEXT,\n terminal_delivery_confirmed_at ${intType()},\n terminal_history_payload TEXT,\n status TEXT NOT NULL,\n attempts ${intType()} NOT NULL DEFAULT 0,\n next_check_at ${intType()} NOT NULL,\n error_message TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL,\n completed_at ${intType()}\n )\n`;\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = buildCreateSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_a2a_continuations\", createSql);\n await ensureIndexExists(\n \"idx_a2a_continuations_status_next\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_status_next ON integration_a2a_continuations(status, next_check_at)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_integration_task\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_integration_task ON integration_a2a_continuations(integration_task_id)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_remote_task\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"a2a_auth_token\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS a2a_auth_token TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"dedupe_key\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS dedupe_key TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"progress_ref\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"progress_ref_claimed\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref_claimed ${intType()} NOT NULL DEFAULT 0`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"verified_artifact_checkpoint\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS verified_artifact_checkpoint TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"terminal_delivery_kind\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS terminal_delivery_kind TEXT`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"terminal_delivery_confirmed_at\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS terminal_delivery_confirmed_at ${intType()}`,\n );\n await ensureColumnExists(\n \"integration_a2a_continuations\",\n \"terminal_history_payload\",\n `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS terminal_history_payload TEXT`,\n );\n await backfillLegacyCompletedDeliveries(client);\n await backfillProgressRefOwners(client);\n await ensureIndexExists(\n \"idx_a2a_continuations_dedupe_key\",\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`,\n );\n await ensureIndexExists(\n \"idx_a2a_continuations_one_progress_owner\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_status_next ON integration_a2a_continuations(status, next_check_at)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_integration_task ON integration_a2a_continuations(integration_task_id)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`,\n ),\n );\n await addColumnIfMissing(\"a2a_auth_token\", \"TEXT\");\n await addColumnIfMissing(\"dedupe_key\", \"TEXT\");\n await addColumnIfMissing(\"progress_ref\", \"TEXT\");\n await addColumnIfMissing(\n \"progress_ref_claimed\",\n `${intType()} NOT NULL DEFAULT 0`,\n );\n await addColumnIfMissing(\"verified_artifact_checkpoint\", \"TEXT\");\n await addColumnIfMissing(\"terminal_delivery_kind\", \"TEXT\");\n await addColumnIfMissing(\"terminal_delivery_confirmed_at\", intType());\n await addColumnIfMissing(\"terminal_history_payload\", \"TEXT\");\n await backfillLegacyCompletedDeliveries(client);\n await backfillProgressRefOwners(client);\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`,\n ),\n );\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nexport async function ensureA2AContinuationsTable(): Promise<void> {\n await ensureTable();\n}\n\nasync function addColumnIfMissing(name: string, definition: string) {\n try {\n await retryOnDdlRace(() =>\n getDbExec().execute(\n `ALTER TABLE integration_a2a_continuations ADD COLUMN ${name} ${definition}`,\n ),\n );\n } catch (err) {\n if (isDuplicateColumnError(err)) return;\n throw err;\n }\n}\n\nasync function backfillProgressRefOwners(\n client: ReturnType<typeof getDbExec>,\n): Promise<void> {\n await client.execute(`\n UPDATE integration_a2a_continuations AS candidate\n SET progress_ref_claimed = 1\n WHERE candidate.progress_ref IS NOT NULL\n AND candidate.status NOT IN ('completed', 'failed')\n AND candidate.progress_ref_claimed = 0\n AND NOT EXISTS (\n SELECT 1\n FROM integration_a2a_continuations AS owner\n WHERE owner.integration_task_id = candidate.integration_task_id\n AND owner.progress_ref_claimed = 1\n )\n AND candidate.id = (\n SELECT selected.id\n FROM integration_a2a_continuations AS selected\n WHERE selected.integration_task_id = candidate.integration_task_id\n AND selected.progress_ref IS NOT NULL\n AND selected.status NOT IN ('completed', 'failed')\n ORDER BY selected.created_at ASC, selected.id ASC\n LIMIT 1\n )\n `);\n}\n\nasync function backfillLegacyCompletedDeliveries(\n client: ReturnType<typeof getDbExec>,\n): Promise<void> {\n await client.execute(`\n UPDATE integration_a2a_continuations\n SET terminal_delivery_kind = 'success',\n terminal_delivery_confirmed_at = COALESCE(completed_at, updated_at)\n WHERE status = 'completed'\n AND terminal_delivery_confirmed_at IS NULL\n `);\n}\n\nexport type A2AContinuationStatus =\n | \"pending\"\n | \"processing\"\n | \"delivering\"\n | \"completed\"\n | \"failed\";\n\nexport type A2ATerminalDeliveryKind = \"success\" | \"failure\";\n\nexport interface A2ATerminalHistoryPayload {\n text: string;\n deliveredAt: string;\n messageRefs: string[];\n artifacts: A2AArtifactIdentity[];\n}\n\nexport type A2AContinuationTaskOutcome =\n | \"active\"\n | \"terminal-delivered\"\n | \"terminal-without-delivery\"\n | \"missing\";\n\nexport interface A2AContinuation {\n id: string;\n integrationTaskId: string;\n platform: string;\n externalThreadId: string;\n incoming: IncomingMessage;\n placeholderRef: string | null;\n progressRef: PlatformRunProgressRef | null;\n progressRefClaimed: boolean;\n ownerEmail: string;\n orgId: string | null;\n agentName: string;\n agentUrl: string;\n dedupeKey: string | null;\n a2aTaskId: string;\n a2aAuthToken: string | null;\n verifiedArtifactCheckpoint: string | null;\n terminalDeliveryKind: A2ATerminalDeliveryKind | null;\n terminalDeliveryConfirmedAt: number | null;\n terminalHistoryPayload: A2ATerminalHistoryPayload | null;\n status: A2AContinuationStatus;\n attempts: number;\n nextCheckAt: number;\n errorMessage: string | null;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nconst MAX_PROGRESS_REF_KIND_CHARS = 128;\nconst MAX_PROGRESS_REF_STREAM_TS_CHARS = 256;\n\n/**\n * Keep only the tiny, adapter-owned continuation reference. Invalid rows are\n * treated as unavailable rather than throwing during a retry sweep.\n */\nfunction parseProgressRef(value: unknown): PlatformRunProgressRef | null {\n if (typeof value !== \"string\" || value.length === 0) return null;\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const { kind, streamTs } = parsed as Record<string, unknown>;\n if (\n typeof kind !== \"string\" ||\n typeof streamTs !== \"string\" ||\n kind.length === 0 ||\n streamTs.length === 0 ||\n kind.length > MAX_PROGRESS_REF_KIND_CHARS ||\n streamTs.length > MAX_PROGRESS_REF_STREAM_TS_CHARS\n ) {\n return null;\n }\n return { kind, streamTs };\n } catch {\n return null;\n }\n}\n\nfunction serializeProgressRef(value: unknown): string | null {\n const parsed = parseProgressRef(\n typeof value === \"string\" ? value : JSON.stringify(value),\n );\n return parsed ? JSON.stringify(parsed) : null;\n}\n\nfunction rowToContinuation(row: Record<string, unknown>): A2AContinuation {\n return {\n id: row.id as string,\n integrationTaskId: row.integration_task_id as string,\n platform: row.platform as string,\n externalThreadId: row.external_thread_id as string,\n incoming: JSON.parse(row.incoming_payload as string) as IncomingMessage,\n placeholderRef: (row.placeholder_ref as string | null) ?? null,\n progressRef: parseProgressRef(row.progress_ref),\n progressRefClaimed: Number(row.progress_ref_claimed ?? 0) === 1,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n agentName: row.agent_name as string,\n agentUrl: row.agent_url as string,\n dedupeKey: (row.dedupe_key as string | null) ?? null,\n a2aTaskId: row.a2a_task_id as string,\n a2aAuthToken: (row.a2a_auth_token as string | null) ?? null,\n verifiedArtifactCheckpoint:\n (row.verified_artifact_checkpoint as string | null) ?? null,\n terminalDeliveryKind:\n row.terminal_delivery_kind === \"success\" ||\n row.terminal_delivery_kind === \"failure\"\n ? row.terminal_delivery_kind\n : null,\n terminalDeliveryConfirmedAt:\n row.terminal_delivery_confirmed_at == null\n ? null\n : Number(row.terminal_delivery_confirmed_at),\n terminalHistoryPayload: parseTerminalHistoryPayload(\n row.terminal_history_payload,\n ),\n status: row.status as A2AContinuationStatus,\n attempts: Number(row.attempts ?? 0),\n nextCheckAt: Number(row.next_check_at ?? 0),\n errorMessage: (row.error_message as string | null) ?? null,\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n completedAt:\n row.completed_at == null ? null : Number(row.completed_at as number),\n };\n}\n\nfunction parseTerminalHistoryPayload(\n value: unknown,\n): A2ATerminalHistoryPayload | null {\n if (typeof value !== \"string\" || !value) return null;\n try {\n const parsed = JSON.parse(value) as Partial<A2ATerminalHistoryPayload>;\n if (\n typeof parsed.text !== \"string\" ||\n typeof parsed.deliveredAt !== \"string\" ||\n !Array.isArray(parsed.messageRefs) ||\n !parsed.messageRefs.every((ref) => typeof ref === \"string\") ||\n !Array.isArray(parsed.artifacts)\n ) {\n return null;\n }\n return {\n text: parsed.text,\n deliveredAt: parsed.deliveredAt,\n messageRefs: parsed.messageRefs,\n artifacts: parsed.artifacts.filter(\n (artifact): artifact is A2AArtifactIdentity =>\n !!artifact &&\n typeof artifact === \"object\" &&\n !Array.isArray(artifact) &&\n typeof (artifact as { id?: unknown }).id === \"string\" &&\n typeof (artifact as { resourceType?: unknown }).resourceType ===\n \"string\" &&\n typeof (artifact as { sourceAction?: unknown }).sourceAction ===\n \"string\",\n ),\n };\n } catch {\n return null;\n }\n}\n\nexport async function insertA2AContinuation(input: {\n integrationTaskId: string;\n platform: string;\n externalThreadId: string;\n incoming: IncomingMessage;\n placeholderRef?: string | null;\n progressRef?: PlatformRunProgressRef | null;\n ownerEmail: string;\n orgId?: string | null;\n agentName: string;\n agentUrl: string;\n dedupeKey?: string | null;\n a2aTaskId: string;\n a2aAuthToken?: string | null;\n}): Promise<A2AContinuation> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const id = `a2a-cont-${now}-${Math.random().toString(36).slice(2, 8)}`;\n const payload = JSON.stringify(input.incoming);\n const progressRef = serializeProgressRef(input.progressRef);\n\n try {\n await client.execute({\n sql: `INSERT INTO integration_a2a_continuations\n (id, integration_task_id, platform, external_thread_id, incoming_payload,\n placeholder_ref, progress_ref, progress_ref_claimed, owner_email, org_id, agent_name, agent_url, dedupe_key, a2a_task_id, a2a_auth_token,\n status, attempts, next_check_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.integrationTaskId,\n input.platform,\n input.externalThreadId,\n payload,\n input.placeholderRef ?? null,\n null,\n 0,\n input.ownerEmail,\n input.orgId ?? null,\n input.agentName,\n input.agentUrl,\n input.dedupeKey ?? null,\n input.a2aTaskId,\n input.a2aAuthToken ?? null,\n \"pending\",\n 0,\n now,\n now,\n now,\n ],\n });\n } catch (err: any) {\n if (!isDuplicateContinuationError(err)) throw err;\n const existing = await findA2AContinuation(\n input.integrationTaskId,\n input.agentUrl,\n input.a2aTaskId,\n );\n if (existing) {\n // A retry can reach this row after the original invocation created it\n // without a resumable progress surface (or with one that has gone\n // stale). Keep the most recent valid adapter reference for active work,\n // but never resurrect short-lived delivery state after a terminal row\n // has deliberately scrubbed it.\n if (\n progressRef &&\n existing.status !== \"completed\" &&\n existing.status !== \"failed\"\n ) {\n if (existing.progressRefClaimed) {\n if (JSON.stringify(existing.progressRef) !== progressRef) {\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET progress_ref = ?, updated_at = ?\n WHERE id = ? AND status NOT IN ('completed', 'failed')\n AND progress_ref_claimed = 1\n AND (progress_ref IS NULL OR progress_ref <> ?)`,\n args: [progressRef, now, existing.id, progressRef],\n });\n }\n } else {\n await claimA2AContinuationProgressRef(existing.id, progressRef);\n }\n return (await getA2AContinuation(existing.id)) ?? existing;\n }\n return existing;\n }\n throw err;\n }\n\n if (progressRef) {\n await claimA2AContinuationProgressRef(id, progressRef);\n }\n return (await getA2AContinuation(id))!;\n}\n\n/**\n * A native platform stream has one terminal completion. Claim it for a single\n * downstream continuation, and retain the ownership marker after terminal\n * cleanup scrubs the short-lived stream reference. The partial unique index\n * makes concurrent downstream inserts safe across processes.\n */\nasync function claimA2AContinuationProgressRef(\n id: string,\n progressRef: string,\n): Promise<void> {\n try {\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET progress_ref = ?, progress_ref_claimed = 1\n WHERE id = ? AND progress_ref_claimed = 0`,\n args: [progressRef, id],\n });\n } catch (err) {\n // A sibling continuation already owns this stream and will finalize it.\n // This continuation still delivers through the normal response path.\n if (isDuplicateContinuationError(err)) return;\n throw err;\n }\n}\n\nexport async function getA2AContinuationForIntegrationTask(\n integrationTaskId: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ?\n ORDER BY created_at ASC\n LIMIT 1`,\n args: [integrationTaskId],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function hasActiveA2AContinuationsForIntegrationTask(\n integrationTaskId: string,\n): Promise<boolean> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT 1 AS active FROM integration_a2a_continuations\n WHERE integration_task_id = ?\n AND status IN ('pending', 'processing', 'delivering')\n LIMIT 1`,\n args: [integrationTaskId],\n });\n return rows.length > 0;\n}\n\nexport async function getA2AContinuationTaskOutcome(\n integrationTaskId: string,\n): Promise<A2AContinuationTaskOutcome> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT status, terminal_delivery_confirmed_at\n FROM integration_a2a_continuations\n WHERE integration_task_id = ?`,\n args: [integrationTaskId],\n });\n if (rows.length === 0) return \"missing\";\n if (\n rows.some((row) =>\n [\"pending\", \"processing\", \"delivering\"].includes(String(row.status)),\n )\n ) {\n return \"active\";\n }\n return rows.every((row) => row.terminal_delivery_confirmed_at != null)\n ? \"terminal-delivered\"\n : \"terminal-without-delivery\";\n}\n\nexport async function hasPendingConfirmedA2ADeliveryForIntegrationTask(\n integrationTaskId: string,\n): Promise<boolean> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT 1 AS confirmed FROM integration_a2a_continuations\n WHERE integration_task_id = ?\n AND status IN ('pending', 'processing', 'delivering')\n AND terminal_delivery_confirmed_at IS NOT NULL\n LIMIT 1`,\n args: [integrationTaskId],\n });\n return rows.length > 0;\n}\n\nexport async function hasOnlyLegacyFailedA2AContinuationsForIntegrationTask(\n integrationTaskId: string,\n): Promise<boolean> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT status, terminal_delivery_kind,\n terminal_delivery_confirmed_at, terminal_history_payload\n FROM integration_a2a_continuations\n WHERE integration_task_id = ?`,\n args: [integrationTaskId],\n });\n return (\n rows.length > 0 &&\n rows.every(\n (row) =>\n String(row.status) === \"failed\" &&\n row.terminal_delivery_kind == null &&\n row.terminal_delivery_confirmed_at == null &&\n row.terminal_history_payload == null,\n )\n );\n}\n\nexport async function failA2AContinuationsForIntegrationTask(\n integrationTaskId: string,\n errorMessage: string,\n): Promise<void> {\n await ensureTable();\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = 'failed', error_message = ?, updated_at = ?, completed_at = ?,\n verified_artifact_checkpoint = NULL\n WHERE integration_task_id = ?\n AND status IN ('pending', 'processing', 'delivering')\n AND terminal_delivery_confirmed_at IS NULL`,\n args: [errorMessage.slice(0, 2000), now, now, integrationTaskId],\n });\n}\n\nexport async function getA2AContinuationsForIntegrationTaskAgent(\n integrationTaskId: string,\n agentUrl: string,\n dedupeKey?: string | null,\n): Promise<A2AContinuation[]> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute(\n dedupeKey\n ? {\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ? AND dedupe_key = ?\n ORDER BY created_at ASC`,\n args: [integrationTaskId, agentUrl, dedupeKey],\n }\n : {\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ?\n ORDER BY created_at ASC`,\n args: [integrationTaskId, agentUrl],\n },\n );\n return rows.map((row) => rowToContinuation(row as Record<string, unknown>));\n}\n\nfunction isDuplicateContinuationError(err: unknown): boolean {\n const e = err as { code?: string; message?: string } | null;\n if (!e) return false;\n if (e.code === \"23505\") return true;\n const msg = String(e.message ?? \"\").toLowerCase();\n return (\n msg.includes(\"unique\") ||\n msg.includes(\"duplicate entry\") ||\n msg.includes(\"duplicate key\")\n );\n}\n\nasync function findA2AContinuation(\n integrationTaskId: string,\n agentUrl: string,\n a2aTaskId: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations\n WHERE integration_task_id = ? AND agent_url = ? AND a2a_task_id = ?\n LIMIT 1`,\n args: [integrationTaskId, agentUrl, a2aTaskId],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function getA2AContinuation(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_a2a_continuations WHERE id = ? LIMIT 1`,\n args: [id],\n });\n return rows[0] ? rowToContinuation(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function claimA2AContinuation(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const processingCutoff = now - PROCESSING_STUCK_AFTER_MS;\n const staleNextCheckCutoff = now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS;\n const result = await client.execute({\n sql: isPostgres()\n ? `UPDATE integration_a2a_continuations\n SET status = ?, attempts = attempts + 1, updated_at = ?\n WHERE id = ?\n AND (\n status = 'pending'\n OR (\n status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)\n )\n )\n RETURNING *`\n : `UPDATE integration_a2a_continuations\n SET status = ?, attempts = attempts + 1, updated_at = ?\n WHERE id = ?\n AND (\n status = 'pending'\n OR (\n status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)\n )\n )`,\n args: [\"processing\", now, id, processingCutoff, staleNextCheckCutoff],\n });\n const rows = result.rows ?? [];\n if (isPostgres()) {\n return rows[0]\n ? rowToContinuation(rows[0] as Record<string, unknown>)\n : null;\n }\n const affected = (result as any)?.rowsAffected ?? (result as any)?.rowCount;\n if (affected === 0) return null;\n const fetched = await getA2AContinuation(id);\n if (!fetched || fetched.status !== \"processing\") return null;\n return fetched;\n}\n\nexport async function claimDueA2AContinuations(\n limit = 5,\n): Promise<A2AContinuation[]> {\n const ids = await recoverDueA2AContinuationIds(limit);\n const claimed: A2AContinuation[] = [];\n for (const id of ids) {\n const continuation = await claimA2AContinuation(id);\n if (continuation) claimed.push(continuation);\n }\n return claimed;\n}\n\n/**\n * Makes stale leases eligible again and returns a bounded set of due ids.\n *\n * This intentionally does not claim anything. Durable schedulers use it only\n * to wake the normal processor, whose atomic claim remains the sole progress\n * and delivery owner under overlapping scheduler/self-dispatch executions.\n */\nexport async function recoverDueA2AContinuationIds(\n limit = 5,\n integrationTaskIds?: string[],\n confirmedDeliveryOnly = false,\n): Promise<string[]> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const processingCutoff = now - PROCESSING_STUCK_AFTER_MS;\n const staleNextCheckCutoff = now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS;\n if (integrationTaskIds && integrationTaskIds.length === 0) return [];\n const taskFilter = integrationTaskIds?.length\n ? ` AND integration_task_id IN (${integrationTaskIds.map(() => \"?\").join(\", \")})`\n : \"\";\n const taskArgs = integrationTaskIds ?? [];\n const receiptFilter = confirmedDeliveryOnly\n ? \" AND terminal_delivery_confirmed_at IS NOT NULL\"\n : \"\";\n // If a processor dies after a provider receipt, retry history-only custody\n // as soon as its short follow-up deadline passes. A pre-receipt delivery\n // claim retains the longer stale cutoff before an at-least-once resend.\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE status = 'delivering'\n AND ((terminal_delivery_confirmed_at IS NOT NULL AND next_check_at <= ?)\n OR updated_at <= ?)${taskFilter}${receiptFilter}`,\n args: [\"pending\", now, now, now, now - 5 * 60 * 1000, ...taskArgs],\n });\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE status = 'processing'\n AND (updated_at <= ? OR next_check_at <= ?)${taskFilter}${receiptFilter}`,\n args: [\n \"pending\",\n now,\n now,\n processingCutoff,\n staleNextCheckCutoff,\n ...taskArgs,\n ],\n });\n const { rows } = await client.execute({\n sql: `SELECT id FROM integration_a2a_continuations\n WHERE status = 'pending' AND next_check_at <= ?${taskFilter}${receiptFilter}\n ORDER BY next_check_at ASC\n LIMIT ?`,\n args: [now, ...taskArgs, limit],\n });\n return rows.map((row) => row.id as string);\n}\n\nexport async function listRecoverableA2AIntegrationTaskIds(\n limit = 50,\n): Promise<string[]> {\n const tasks = await listRecoverableA2AIntegrationTasks(limit);\n return tasks.map((task) => task.id);\n}\n\nexport interface RecoverableA2AIntegrationTask {\n id: string;\n platform: string;\n externalThreadId: string;\n dispatchScope: string | null;\n status: string;\n hasPendingConfirmedDelivery: boolean;\n}\n\n/**\n * Read due continuation owners and their rollout scope in one query. Recovery\n * can filter the canary in memory without an N+1 pending-task lookup loop.\n */\nexport async function listRecoverableA2AIntegrationTasks(\n limit = 50,\n): Promise<RecoverableA2AIntegrationTask[]> {\n await ensureTable();\n const now = Date.now();\n const { rows } = await getDbExec().execute({\n sql: `SELECT DISTINCT c.integration_task_id, t.platform,\n t.external_thread_id, t.dispatch_scope, t.status,\n EXISTS (\n SELECT 1 FROM integration_a2a_continuations receipt\n WHERE receipt.integration_task_id = c.integration_task_id\n AND receipt.terminal_delivery_confirmed_at IS NOT NULL\n AND receipt.status IN ('pending', 'processing', 'delivering')\n ) AS has_pending_confirmed_delivery\n FROM integration_a2a_continuations c\n INNER JOIN integration_pending_tasks t\n ON t.id = c.integration_task_id\n WHERE t.status = 'processing'\n AND ((c.status = 'pending' AND c.next_check_at <= ?)\n OR (c.status = 'processing' AND\n (c.updated_at <= ? OR c.next_check_at <= ?))\n OR (c.status = 'delivering' AND\n ((c.terminal_delivery_confirmed_at IS NOT NULL AND c.next_check_at <= ?)\n OR c.updated_at <= ?)))\n ORDER BY c.integration_task_id ASC\n LIMIT ?`,\n args: [\n now,\n now - PROCESSING_STUCK_AFTER_MS,\n now - PROCESSING_NEXT_CHECK_STALE_AFTER_MS,\n now,\n now - 5 * 60 * 1000,\n Math.max(1, Math.min(Math.floor(limit), 200)),\n ],\n });\n return rows.map((row) => ({\n id: String(row.integration_task_id),\n platform: String(row.platform),\n externalThreadId: String(row.external_thread_id),\n dispatchScope: (row.dispatch_scope as string | null) ?? null,\n status: String(row.status),\n hasPendingConfirmedDelivery:\n row.has_pending_confirmed_delivery === true ||\n Number(row.has_pending_confirmed_delivery ?? 0) === 1,\n }));\n}\n\nexport async function claimA2AContinuationDelivery(\n id: string,\n): Promise<A2AContinuation | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: isPostgres()\n ? `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?\n WHERE id = ? AND status = 'processing'\n RETURNING *`\n : `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?\n WHERE id = ? AND status = 'processing'`,\n args: [\"delivering\", now, id],\n });\n const rows = result.rows ?? [];\n if (isPostgres()) {\n return rows[0]\n ? rowToContinuation(rows[0] as Record<string, unknown>)\n : null;\n }\n const affected = (result as any)?.rowsAffected ?? (result as any)?.rowCount;\n if (affected === 0) return null;\n const fetched = await getA2AContinuation(id);\n if (!fetched || fetched.status !== \"delivering\") return null;\n return fetched;\n}\n\nexport async function rescheduleA2AContinuation(\n id: string,\n delayMs: number,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, next_check_at = ?, updated_at = ?\n WHERE id = ? AND status IN ('processing', 'delivering')`,\n args: [\"pending\", now + delayMs, now, id],\n });\n}\n\nexport async function retainA2AUnconfirmedDeliveryClaim(\n id: string,\n): Promise<void> {\n await ensureTable();\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET next_check_at = ?, updated_at = ?\n WHERE id = ? AND status = 'delivering'\n AND terminal_delivery_confirmed_at IS NULL`,\n args: [now + PROCESSING_STUCK_AFTER_MS, now, id],\n });\n}\n\nexport async function saveA2AVerifiedArtifactCheckpoint(\n id: string,\n checkpoint: string,\n): Promise<string | null> {\n await ensureTable();\n const normalized = checkpoint.trim();\n if (!normalized) return null;\n if (normalized.length > MAX_VERIFIED_ARTIFACT_CHECKPOINT_CHARS) {\n throw new Error(\n `Verified artifact checkpoint exceeds ${MAX_VERIFIED_ARTIFACT_CHECKPOINT_CHARS} characters`,\n );\n }\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET verified_artifact_checkpoint = ?, updated_at = ?\n WHERE id = ? AND status IN ('pending', 'processing', 'delivering')`,\n args: [normalized, now, id],\n });\n const persisted = await getA2AContinuation(id);\n return persisted?.verifiedArtifactCheckpoint === normalized\n ? normalized\n : null;\n}\n\nexport async function recordA2ATerminalDeliveryReceipt(\n id: string,\n kind: A2ATerminalDeliveryKind,\n historyPayload: A2ATerminalHistoryPayload,\n errorMessage?: string,\n): Promise<A2AContinuation> {\n await ensureTable();\n const serializedPayload = JSON.stringify(historyPayload);\n if (serializedPayload.length > MAX_TERMINAL_HISTORY_PAYLOAD_CHARS) {\n throw new Error(\n `Terminal A2A history payload exceeds ${MAX_TERMINAL_HISTORY_PAYLOAD_CHARS} characters`,\n );\n }\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = 'delivering', terminal_delivery_kind = ?,\n terminal_delivery_confirmed_at = COALESCE(terminal_delivery_confirmed_at, ?),\n terminal_history_payload = ?, next_check_at = ?, updated_at = ?,\n error_message = ?\n WHERE id = ?\n AND status IN ('processing', 'delivering')\n AND (terminal_delivery_confirmed_at IS NULL\n OR terminal_delivery_kind = ?)`,\n args: [\n kind,\n now,\n serializedPayload,\n now + TERMINAL_HISTORY_FINALIZATION_LEASE_MS,\n now,\n errorMessage?.slice(0, 2000) ?? null,\n id,\n kind,\n ],\n });\n const persisted = await getA2AContinuation(id);\n if (\n persisted?.status !== \"delivering\" ||\n persisted.terminalDeliveryKind !== kind ||\n persisted.terminalDeliveryConfirmedAt == null ||\n JSON.stringify(persisted.terminalHistoryPayload) !== serializedPayload\n ) {\n throw new Error(\"Terminal A2A delivery confirmation did not persist\");\n }\n return persisted;\n}\n\nexport async function finalizeA2ATerminalHistory(id: string): Promise<void> {\n await ensureTable();\n const continuation = await getA2AContinuation(id);\n if (\n continuation &&\n (continuation.status === \"completed\" || continuation.status === \"failed\") &&\n continuation.terminalDeliveryConfirmedAt != null &&\n continuation.terminalHistoryPayload == null\n ) {\n return;\n }\n if (\n !continuation?.terminalDeliveryKind ||\n continuation.terminalDeliveryConfirmedAt == null ||\n !continuation.terminalHistoryPayload\n ) {\n throw new Error(\"Terminal A2A history cannot finalize without a receipt\");\n }\n const now = Date.now();\n const status =\n continuation.terminalDeliveryKind === \"success\" ? \"completed\" : \"failed\";\n await getDbExec().execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?, completed_at = ?, incoming_payload = ?,\n a2a_auth_token = NULL, progress_ref = NULL,\n verified_artifact_checkpoint = NULL, terminal_history_payload = NULL\n WHERE id = ? AND status IN ('pending', 'processing', 'delivering')\n AND terminal_delivery_confirmed_at IS NOT NULL`,\n args: [status, now, now, \"{}\", id],\n });\n const persisted = await getA2AContinuation(id);\n if (\n persisted?.status !== status ||\n persisted.terminalHistoryPayload != null\n ) {\n throw new Error(\"Terminal A2A history finalization did not persist\");\n }\n}\n\nexport async function completeA2AContinuation(id: string): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?, completed_at = ?,\n incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL,\n verified_artifact_checkpoint = NULL,\n terminal_delivery_kind = COALESCE(terminal_delivery_kind, 'success'),\n terminal_delivery_confirmed_at = COALESCE(terminal_delivery_confirmed_at, ?),\n terminal_history_payload = NULL\n WHERE id = ? AND status IN ('processing', 'delivering', 'completed')`,\n args: [\"completed\", now, now, \"{}\", now, id],\n });\n}\n\nexport async function failA2AContinuation(\n id: string,\n errorMessage: string,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n await client.execute({\n sql: `UPDATE integration_a2a_continuations\n SET status = ?, updated_at = ?, error_message = ?,\n incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL,\n verified_artifact_checkpoint = NULL\n WHERE id = ? AND status <> 'completed'`,\n args: [\"failed\", now, errorMessage.slice(0, 2000), \"{}\", id],\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/integrations/adapters/slack.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAShB,MAAM,aAAa,CAAC;AAmErB,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,eAAe,CAqkBjB;AAkBD,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/integrations/adapters/slack.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAUhB,MAAM,aAAa,CAAC;AAsErB,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,eAAe,CAwnBjB;AAkBD,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { createError, getHeader, readRawBody } from "h3";
2
3
  import { resolveSecret } from "../../server/credential-provider.js";
3
4
  import { getRequestContext } from "../../server/request-context.js";
@@ -26,6 +27,9 @@ const SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
26
27
  const SLACK_IDENTITY_CACHE_MAX_ENTRIES = 1_000;
27
28
  const SLACK_TOKEN_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
28
29
  const SLACK_TOKEN_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
30
+ const SLACK_DELIVERY_RECONCILIATION_PAGE_LIMIT = 200;
31
+ const SLACK_DELIVERY_RECONCILIATION_MAX_PAGES = 3;
32
+ const SLACK_DELIVERY_MARKER_PREFIX = "agent_native_terminal_";
29
33
  const slackTokenIdentityCache = new Map();
30
34
  const slackIdentityCache = new Map();
31
35
  // Deduped system notices send at most once per key per TTL so senders are
@@ -361,6 +365,13 @@ export function slackAdapter(options = {}) {
361
365
  }
362
366
  const restChunks = chunks.slice(1);
363
367
  const messageRefs = [];
368
+ const freshChunkIndexes = [
369
+ ...(!placeholderRef ? [0] : []),
370
+ ...restChunks.map((_, index) => index + 1),
371
+ ];
372
+ const reconciledRefs = opts?.idempotencyKey && freshChunkIndexes.length > 0
373
+ ? await reconcileSlackDeliveryChunks(token, channelId, threadTs, opts.idempotencyKey, freshChunkIndexes, opts.reconcileAfter, opts.signal)
374
+ : new Map();
364
375
  const finalBlocks = blocks ??
365
376
  buildResponseBlocks(firstChunk, {
366
377
  threadDeepLinkUrl: message.platformContext
@@ -377,19 +388,24 @@ export function slackAdapter(options = {}) {
377
388
  try {
378
389
  if (placeholderRef) {
379
390
  // Replace the "thinking…" placeholder in place.
380
- const res = await slackApiFetch("https://slack.com/api/chat.update", {
391
+ const data = (await slackApiJson("https://slack.com/api/chat.update", {
381
392
  method: "POST",
382
393
  headers: {
383
394
  Authorization: `Bearer ${token}`,
384
395
  "Content-Type": "application/json",
385
396
  },
386
397
  body: JSON.stringify({ ...baseBody, ts: placeholderRef }),
387
- });
388
- const data = (await res.json());
398
+ signal: opts?.signal,
399
+ }));
389
400
  if (!data.ok) {
390
401
  console.error("[slack] chat.update error:", data.error);
402
+ if (opts?.strictTargetRef) {
403
+ throw new Error(data.error || "chat.update failed");
404
+ }
391
405
  // Fall back to a fresh post so the user still sees a reply
392
- const postedTs = await postFresh(token, channelId, threadTs, baseBody);
406
+ const postedTs = await postFresh(token, channelId, threadTs, opts?.idempotencyKey
407
+ ? withSlackDeliveryMarker(baseBody, opts.idempotencyKey, 0)
408
+ : baseBody, opts?.signal);
393
409
  if (postedTs)
394
410
  messageRefs.push(postedTs);
395
411
  }
@@ -398,9 +414,17 @@ export function slackAdapter(options = {}) {
398
414
  }
399
415
  }
400
416
  else {
401
- const postedTs = await postFresh(token, channelId, threadTs, baseBody);
402
- if (postedTs)
403
- messageRefs.push(postedTs);
417
+ const reconciledRef = reconciledRefs.get(0);
418
+ if (reconciledRef) {
419
+ messageRefs.push(reconciledRef);
420
+ }
421
+ else {
422
+ const postedTs = await postFresh(token, channelId, threadTs, opts?.idempotencyKey
423
+ ? withSlackDeliveryMarker(baseBody, opts.idempotencyKey, 0)
424
+ : baseBody, opts?.signal);
425
+ if (postedTs)
426
+ messageRefs.push(postedTs);
427
+ }
404
428
  }
405
429
  // Clear the AI-assistant "is thinking…" status now that we've
406
430
  // delivered the final answer. Empty status clears it.
@@ -408,14 +432,23 @@ export function slackAdapter(options = {}) {
408
432
  setSlackAssistantStatus(token, channelId, threadTs, "");
409
433
  }
410
434
  // Overflow chunks (rare) — post as plain follow-ups in the same thread
411
- for (const chunk of restChunks) {
412
- const postedTs = await postFresh(token, channelId, threadTs, {
435
+ for (const [index, chunk] of restChunks.entries()) {
436
+ const chunkIndex = index + 1;
437
+ const reconciledRef = reconciledRefs.get(chunkIndex);
438
+ if (reconciledRef) {
439
+ messageRefs.push(reconciledRef);
440
+ continue;
441
+ }
442
+ const overflowBody = {
413
443
  channel: channelId,
414
444
  text: chunk,
415
445
  unfurl_links: false,
416
446
  unfurl_media: false,
417
447
  mrkdwn: true,
418
- });
448
+ };
449
+ const postedTs = await postFresh(token, channelId, threadTs, opts?.idempotencyKey
450
+ ? withSlackDeliveryMarker(overflowBody, opts.idempotencyKey, chunkIndex)
451
+ : overflowBody, opts?.signal);
419
452
  if (postedTs)
420
453
  messageRefs.push(postedTs);
421
454
  }
@@ -497,15 +530,14 @@ export function slackAdapter(options = {}) {
497
530
  if (target.threadRef)
498
531
  body.thread_ts = target.threadRef;
499
532
  try {
500
- const res = await slackApiFetch("https://slack.com/api/chat.postMessage", {
533
+ const data = (await slackApiJson("https://slack.com/api/chat.postMessage", {
501
534
  method: "POST",
502
535
  headers: {
503
536
  Authorization: `Bearer ${token}`,
504
537
  "Content-Type": "application/json",
505
538
  },
506
539
  body: JSON.stringify(body),
507
- });
508
- const data = (await res.json());
540
+ }));
509
541
  if (!data.ok) {
510
542
  throw new Error(data.error || "chat.postMessage failed");
511
543
  }
@@ -838,7 +870,7 @@ function markdownToSlackMrkdwn(text) {
838
870
  * Pure best-effort — failures never block the response.
839
871
  */
840
872
  function setSlackAssistantStatus(token, channelId, threadTs, status) {
841
- slackApiFetch("https://slack.com/api/assistant.threads.setStatus", {
873
+ slackApiJson("https://slack.com/api/assistant.threads.setStatus", {
842
874
  method: "POST",
843
875
  headers: {
844
876
  Authorization: `Bearer ${token}`,
@@ -882,7 +914,7 @@ function buildResponseBlocks(text, opts) {
882
914
  * Post a fresh message to a thread. Used as the placeholder-fallback path
883
915
  * (e.g. when chat.update fails) and for follow-up overflow chunks.
884
916
  */
885
- async function postFresh(token, channelId, threadTs, body) {
917
+ async function postFresh(token, channelId, threadTs, body, signal) {
886
918
  const hasBlocks = Array.isArray(body.blocks) && body.blocks.length > 0;
887
919
  if (typeof body.text === "string" &&
888
920
  body.text.trim().length === 0 &&
@@ -895,35 +927,128 @@ async function postFresh(token, channelId, threadTs, body) {
895
927
  };
896
928
  if (threadTs && !payload.thread_ts)
897
929
  payload.thread_ts = threadTs;
898
- const res = await slackApiFetch("https://slack.com/api/chat.postMessage", {
930
+ const data = (await slackApiJson("https://slack.com/api/chat.postMessage", {
899
931
  method: "POST",
900
932
  headers: {
901
933
  Authorization: `Bearer ${token}`,
902
934
  "Content-Type": "application/json",
903
935
  },
904
936
  body: JSON.stringify(payload),
905
- });
906
- const data = (await res.json());
937
+ signal,
938
+ }));
907
939
  if (!data.ok) {
908
940
  console.error("[slack] chat.postMessage error:", data.error);
909
941
  throw new Error(data.error || "chat.postMessage failed");
910
942
  }
911
943
  return data.ts;
912
944
  }
913
- async function slackApiFetch(url, init, timeoutMs = SLACK_API_TIMEOUT_MS) {
945
+ function slackDeliveryMarker(key, chunkIndex) {
946
+ const digest = createHash("sha256")
947
+ .update(`${key}:${chunkIndex}`)
948
+ .digest("hex")
949
+ .slice(0, 32);
950
+ return `${SLACK_DELIVERY_MARKER_PREFIX}${digest}`;
951
+ }
952
+ function withSlackDeliveryMarker(body, key, chunkIndex) {
953
+ const marker = slackDeliveryMarker(key, chunkIndex);
954
+ const blocks = Array.isArray(body.blocks) ? body.blocks : [];
955
+ if (blocks.length > 0) {
956
+ const [first, ...rest] = blocks;
957
+ if (first && typeof first === "object" && !Array.isArray(first)) {
958
+ return {
959
+ ...body,
960
+ blocks: [
961
+ { ...first, block_id: marker },
962
+ ...rest,
963
+ ],
964
+ };
965
+ }
966
+ }
967
+ return {
968
+ ...body,
969
+ blocks: [
970
+ {
971
+ type: "section",
972
+ block_id: marker,
973
+ text: { type: "mrkdwn", text: String(body.text ?? "") },
974
+ },
975
+ ],
976
+ };
977
+ }
978
+ async function reconcileSlackDeliveryChunks(token, channelId, threadTs, key, chunkIndexes, reconcileAfter, signal) {
979
+ if (!threadTs) {
980
+ throw new Error("Cannot reconcile an idempotent Slack delivery without a thread timestamp");
981
+ }
982
+ const refs = new Map();
983
+ const expectedMarkers = new Map(chunkIndexes.map((chunkIndex) => [
984
+ slackDeliveryMarker(key, chunkIndex),
985
+ chunkIndex,
986
+ ]));
987
+ let cursor = "";
988
+ for (let page = 0; page < SLACK_DELIVERY_RECONCILIATION_MAX_PAGES; page += 1) {
989
+ const url = new URL("https://slack.com/api/conversations.replies");
990
+ url.searchParams.set("channel", channelId);
991
+ url.searchParams.set("ts", threadTs);
992
+ url.searchParams.set("limit", String(SLACK_DELIVERY_RECONCILIATION_PAGE_LIMIT));
993
+ if (cursor)
994
+ url.searchParams.set("cursor", cursor);
995
+ if (typeof reconcileAfter === "number" && reconcileAfter > 0) {
996
+ url.searchParams.set("oldest", String(Math.floor(reconcileAfter / 1000)));
997
+ url.searchParams.set("inclusive", "true");
998
+ }
999
+ const body = (await slackApiJson(url.toString(), {
1000
+ headers: { Authorization: `Bearer ${token}` },
1001
+ signal,
1002
+ }));
1003
+ if (!body.ok) {
1004
+ throw new Error(body.error || "conversations.replies failed");
1005
+ }
1006
+ for (const message of body.messages ?? []) {
1007
+ if (typeof message.ts !== "string")
1008
+ continue;
1009
+ for (const block of message.blocks ?? []) {
1010
+ if (typeof block.block_id !== "string")
1011
+ continue;
1012
+ const chunkIndex = expectedMarkers.get(block.block_id);
1013
+ if (chunkIndex !== undefined)
1014
+ refs.set(chunkIndex, message.ts);
1015
+ }
1016
+ }
1017
+ if (refs.size === expectedMarkers.size)
1018
+ return refs;
1019
+ cursor = body.response_metadata?.next_cursor?.trim() ?? "";
1020
+ if (!cursor)
1021
+ return refs;
1022
+ }
1023
+ throw new Error("Slack delivery reconciliation exceeded the bounded thread scan");
1024
+ }
1025
+ async function slackApiJson(url, init, timeoutMs = SLACK_API_TIMEOUT_MS) {
914
1026
  const controller = typeof AbortController !== "undefined" ? new AbortController() : undefined;
1027
+ const externalSignal = init.signal;
1028
+ const abortFromExternal = () => controller?.abort(externalSignal?.reason);
1029
+ if (controller && externalSignal) {
1030
+ if (externalSignal.aborted)
1031
+ abortFromExternal();
1032
+ else {
1033
+ externalSignal.addEventListener("abort", abortFromExternal, {
1034
+ once: true,
1035
+ });
1036
+ }
1037
+ }
915
1038
  const timer = controller
916
1039
  ? setTimeout(() => controller.abort(), timeoutMs)
917
1040
  : undefined;
918
1041
  try {
919
- return await fetch(url, {
1042
+ const response = await fetch(url, {
920
1043
  ...init,
921
1044
  signal: controller?.signal ?? init.signal,
922
1045
  });
1046
+ return (await response.json());
923
1047
  }
924
1048
  finally {
925
1049
  if (timer)
926
1050
  clearTimeout(timer);
1051
+ externalSignal?.removeEventListener("abort", abortFromExternal);
927
1052
  }
928
1053
  }
929
1054
  async function resolveSlackThreadPermalink(channelId, threadTs, resolvedToken) {
@@ -937,8 +1062,7 @@ async function resolveSlackThreadPermalink(channelId, threadTs, resolvedToken) {
937
1062
  const url = new URL("https://slack.com/api/chat.getPermalink");
938
1063
  url.searchParams.set("channel", channelId);
939
1064
  url.searchParams.set("message_ts", threadTs);
940
- const res = await slackApiFetch(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, SLACK_PERMALINK_TIMEOUT_MS);
941
- const data = (await res.json());
1065
+ const data = (await slackApiJson(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, SLACK_PERMALINK_TIMEOUT_MS));
942
1066
  if (!data.ok || typeof data.permalink !== "string")
943
1067
  return undefined;
944
1068
  const permalink = new URL(data.permalink);
@@ -1013,8 +1137,7 @@ async function slackJson(token, method, params, timeoutMs = 2_000) {
1013
1137
  for (const [key, value] of Object.entries(params)) {
1014
1138
  url.searchParams.set(key, value);
1015
1139
  }
1016
- const response = await slackApiFetch(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, timeoutMs);
1017
- const body = (await response.json());
1140
+ const body = await slackApiJson(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, timeoutMs);
1018
1141
  return body.ok ? body : null;
1019
1142
  }
1020
1143
  catch {
@@ -1307,16 +1430,16 @@ function delegatedProgressDetails(agent, state, elapsedSeconds, detail) {
1307
1430
  }
1308
1431
  return update ? `${progress} — ${update}` : progress;
1309
1432
  }
1310
- async function postSlackJson(token, method, body) {
1311
- const response = await slackApiFetch(`https://slack.com/api/${method}`, {
1433
+ async function postSlackJson(token, method, body, signal) {
1434
+ const data = await slackApiJson(`https://slack.com/api/${method}`, {
1312
1435
  method: "POST",
1313
1436
  headers: {
1314
1437
  Authorization: `Bearer ${token}`,
1315
1438
  "Content-Type": "application/json",
1316
1439
  },
1317
1440
  body: JSON.stringify(body),
1441
+ signal,
1318
1442
  });
1319
- const data = (await response.json());
1320
1443
  if (!data.ok)
1321
1444
  throw new Error(data.error || `${method} failed`);
1322
1445
  return data;
@@ -1438,6 +1561,7 @@ function createSlackRunProgress(token, incoming, channel, threadTs, streamTs) {
1438
1561
  const taskId = (prefix, explicit) => `${prefix}:${explicit || ++sequence}`.slice(0, 240);
1439
1562
  return {
1440
1563
  ref: { kind: "slack-stream", streamTs },
1564
+ responseTargetRef: streamTs,
1441
1565
  async onEvent(event) {
1442
1566
  if (!cancelControl) {
1443
1567
  const context = getIntegrationRequestContext();
@@ -1589,7 +1713,7 @@ function createSlackRunProgress(token, incoming, channel, threadTs, streamTs) {
1589
1713
  });
1590
1714
  }
1591
1715
  },
1592
- async complete(message) {
1716
+ async complete(message, opts) {
1593
1717
  if (pendingTimer)
1594
1718
  clearTimeout(pendingTimer);
1595
1719
  const finalChunks = [...tasks.entries()].map(([id, task]) => ({
@@ -1633,18 +1757,18 @@ function createSlackRunProgress(token, incoming, channel, threadTs, streamTs) {
1633
1757
  ...(messageBlocks.length || controlBlocks.length
1634
1758
  ? { blocks: [...messageBlocks, ...controlBlocks].slice(0, 50) }
1635
1759
  : {}),
1636
- });
1760
+ }, opts?.signal);
1637
1761
  setSlackAssistantStatus(token, channel, threadTs, "");
1638
1762
  return { status: "delivered", messageRefs: [streamTs] };
1639
1763
  },
1640
- async fail(message) {
1764
+ async fail(message, opts) {
1641
1765
  if (pendingTimer)
1642
1766
  clearTimeout(pendingTimer);
1643
1767
  await postSlackJson(token, "chat.stopStream", {
1644
1768
  channel,
1645
1769
  ts: streamTs,
1646
1770
  markdown_text: message.slice(0, SLACK_MAX_LENGTH),
1647
- }).catch(() => { });
1771
+ }, opts?.signal).catch(() => { });
1648
1772
  setSlackAssistantStatus(token, channel, threadTs, "");
1649
1773
  },
1650
1774
  };