@agent-native/core 0.98.6 → 0.98.8

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 (88) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/docs/content/external-agents.mdx +22 -12
  4. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +8 -2
  5. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +8 -2
  6. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +8 -2
  7. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +8 -2
  8. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +8 -2
  9. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +8 -2
  10. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +8 -2
  11. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +8 -2
  12. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -2
  13. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -2
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/a2a/handlers.ts +6 -5
  16. package/corpus/core/src/a2a/task-store.ts +63 -0
  17. package/corpus/core/src/client/session-replay.ts +90 -6
  18. package/corpus/core/src/integrations/adapters/slack.ts +110 -19
  19. package/corpus/core/src/integrations/identity.ts +103 -39
  20. package/corpus/core/src/integrations/pending-tasks-retry-job.ts +2 -1
  21. package/corpus/core/src/integrations/pending-tasks-store.ts +1 -1
  22. package/corpus/core/src/integrations/plugin.ts +215 -8
  23. package/corpus/core/src/integrations/types.ts +37 -0
  24. package/corpus/core/src/integrations/webhook-handler.ts +1 -0
  25. package/corpus/core/src/mcp/builtin-tools.ts +5 -2
  26. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +4 -1
  27. package/corpus/templates/analytics/AGENTS.md +9 -9
  28. package/corpus/templates/analytics/changelog/2026-07-12-analytics-uses-the-full-in-app-agent-for-multi-step-incident.md +6 -0
  29. package/corpus/templates/analytics/server/handlers/session-replay.ts +15 -9
  30. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +23 -5
  31. package/corpus/templates/analytics/server/lib/session-replay.ts +26 -5
  32. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -1
  33. package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +8 -5
  34. package/corpus/templates/analytics/server/routes/api/session-replay/agent-events.json.get.ts +8 -3
  35. package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +12 -2
  36. package/dist/a2a/handlers.d.ts.map +1 -1
  37. package/dist/a2a/handlers.js +6 -6
  38. package/dist/a2a/handlers.js.map +1 -1
  39. package/dist/a2a/task-store.d.ts +12 -0
  40. package/dist/a2a/task-store.d.ts.map +1 -1
  41. package/dist/a2a/task-store.js +54 -0
  42. package/dist/a2a/task-store.js.map +1 -1
  43. package/dist/client/session-replay.d.ts.map +1 -1
  44. package/dist/client/session-replay.js +71 -9
  45. package/dist/client/session-replay.js.map +1 -1
  46. package/dist/collab/routes.d.ts +1 -1
  47. package/dist/collab/struct-routes.d.ts +1 -1
  48. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  49. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  50. package/dist/integrations/adapters/slack.js +94 -11
  51. package/dist/integrations/adapters/slack.js.map +1 -1
  52. package/dist/integrations/identity.d.ts +19 -2
  53. package/dist/integrations/identity.d.ts.map +1 -1
  54. package/dist/integrations/identity.js +76 -34
  55. package/dist/integrations/identity.js.map +1 -1
  56. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  57. package/dist/integrations/pending-tasks-retry-job.js +2 -1
  58. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  59. package/dist/integrations/pending-tasks-store.js +1 -1
  60. package/dist/integrations/pending-tasks-store.js.map +1 -1
  61. package/dist/integrations/plugin.d.ts.map +1 -1
  62. package/dist/integrations/plugin.js +165 -9
  63. package/dist/integrations/plugin.js.map +1 -1
  64. package/dist/integrations/types.d.ts +32 -0
  65. package/dist/integrations/types.d.ts.map +1 -1
  66. package/dist/integrations/types.js.map +1 -1
  67. package/dist/integrations/webhook-handler.js +1 -0
  68. package/dist/integrations/webhook-handler.js.map +1 -1
  69. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  70. package/dist/mcp/builtin-tools.js +5 -2
  71. package/dist/mcp/builtin-tools.js.map +1 -1
  72. package/dist/notifications/routes.d.ts +1 -1
  73. package/dist/progress/routes.d.ts +1 -1
  74. package/dist/resources/handlers.d.ts +3 -3
  75. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  76. package/dist/server/transcribe-voice.d.ts +1 -1
  77. package/docs/content/external-agents.mdx +22 -12
  78. package/docs/content/locales/ar-SA/external-agents.mdx +8 -2
  79. package/docs/content/locales/de-DE/external-agents.mdx +8 -2
  80. package/docs/content/locales/es-ES/external-agents.mdx +8 -2
  81. package/docs/content/locales/fr-FR/external-agents.mdx +8 -2
  82. package/docs/content/locales/hi-IN/external-agents.mdx +8 -2
  83. package/docs/content/locales/ja-JP/external-agents.mdx +8 -2
  84. package/docs/content/locales/ko-KR/external-agents.mdx +8 -2
  85. package/docs/content/locales/pt-BR/external-agents.mdx +8 -2
  86. package/docs/content/locales/zh-CN/external-agents.mdx +8 -2
  87. package/docs/content/locales/zh-TW/external-agents.mdx +8 -2
  88. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\n\nimport { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport { ensureTableExists, ensureColumnExists } from \"../db/ddl-guard.js\";\nimport type { Task, Message, TaskState, Artifact } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = `\n CREATE TABLE IF NOT EXISTS a2a_tasks (\n id TEXT PRIMARY KEY,\n context_id TEXT,\n status_state TEXT NOT NULL DEFAULT 'submitted',\n status_message TEXT,\n status_timestamp TEXT NOT NULL,\n history TEXT NOT NULL DEFAULT '[]',\n artifacts TEXT NOT NULL DEFAULT '[]',\n metadata TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // PG-guard: probe information_schema before issuing DDL to avoid ACCESS\n // EXCLUSIVE lock contention in fresh background-worker processes.\n await ensureTableExists(\"a2a_tasks\", createSql);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n await ensureColumnExists(\n \"a2a_tasks\",\n \"owner_email\",\n `ALTER TABLE a2a_tasks ADD COLUMN IF NOT EXISTS owner_email TEXT`,\n );\n return;\n }\n\n // SQLite (local dev): no lock problem — keep the original behaviour.\n await client.execute(createSql);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n try {\n await client.execute(\n `ALTER TABLE a2a_tasks ADD COLUMN owner_email TEXT`,\n );\n } catch {\n // Column already exists — expected on every restart after first run.\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\nfunction taskFromRow(row: any): Task & { ownerEmail?: string | null } {\n return {\n id: row.id as string,\n contextId: (row.context_id as string) || undefined,\n status: {\n state: row.status_state as TaskState,\n message: row.status_message\n ? JSON.parse(row.status_message as string)\n : undefined,\n timestamp: row.status_timestamp as string,\n },\n history: JSON.parse(row.history as string),\n artifacts: JSON.parse(row.artifacts as string),\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n ownerEmail: (row.owner_email as string | null) ?? null,\n };\n}\n\nfunction getAffectedRowCount(result: unknown): number | undefined {\n const resultRecord = result as\n | {\n rowsAffected?: number;\n rowCount?: number;\n count?: number;\n }\n | undefined;\n return (\n resultRecord?.rowsAffected ?? resultRecord?.rowCount ?? resultRecord?.count\n );\n}\n\nexport async function createTask(\n message: Message,\n contextId?: string,\n metadata?: Record<string, unknown>,\n ownerEmail?: string | null,\n): Promise<Task> {\n await ensureTable();\n const client = getDbExec();\n const id = crypto.randomUUID();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const task: Task = {\n id,\n contextId,\n status: { state: \"submitted\", timestamp },\n history: [message],\n artifacts: [],\n metadata,\n };\n\n await client.execute({\n sql: `INSERT INTO a2a_tasks (id, context_id, status_state, status_timestamp, history, artifacts, metadata, owner_email, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n contextId ?? null,\n \"submitted\",\n timestamp,\n JSON.stringify([message]),\n \"[]\",\n metadata ? JSON.stringify(metadata) : null,\n ownerEmail ?? null,\n now,\n now,\n ],\n });\n\n return task;\n}\n\n/**\n * Fetch the verified owner email recorded against a task at creation time.\n * Returns null when the task has no owner (legacy rows or unauthenticated\n * deployments) or when the task is missing.\n *\n * Used by `handleGet` / `handleCancel` to reject IDOR access — the JWT-\n * verified caller's email must match `owner_email` to read or cancel.\n */\nexport async function getTaskOwner(id: string): Promise<string | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT owner_email FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n const ownerEmail = (rows[0] as any).owner_email;\n return typeof ownerEmail === \"string\" && ownerEmail ? ownerEmail : null;\n}\n\n/**\n * Atomically claim a task for processing. Only succeeds when the task is in\n * state 'submitted' or 'working' — flipping it to 'processing' so concurrent\n * processors can't pick it up twice. Returns the task if claimed, null if it\n * was already claimed/completed/missing.\n *\n * Used by the cross-platform async processor (`_process-task` route) to avoid\n * duplicate handler runs when retries fire.\n */\nexport async function claimA2ATaskForProcessing(\n id: string,\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'processing',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [timestamp, now, id],\n });\n const affected = getAffectedRowCount(result);\n if (affected === 0) return null;\n\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function getA2ATaskDispatchState(id: string): Promise<{\n id: string;\n statusState: string;\n metadata: Record<string, unknown> | undefined;\n updatedAt: number;\n createdAt: number;\n} | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, status_state, metadata, created_at, updated_at FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n const row = rows[0] as any;\n if (!row) return null;\n return {\n id: row.id as string,\n statusState: row.status_state as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n updatedAt: Number(row.updated_at ?? 0),\n createdAt: Number(row.created_at ?? 0),\n };\n}\n\nexport async function touchQueuedA2ATaskDispatch(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function touchProcessingA2ATask(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function resetStuckA2ATaskForRetry(\n id: string,\n processingCutoff: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'working',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\n/**\n * Fail a processing task once it is stuck. Two independent conditions can\n * trigger this, either of which alone is sufficient:\n * - `updated_at <= processingCutoff`: no heartbeat/progress touch in a\n * while — the processor likely died.\n * - `created_at <= createdAtCutoff` — a hard wall on total run time. A\n * hung await inside a still-alive process keeps `updated_at` fresh via\n * the liveness heartbeat forever, so staleness alone never trips; age\n * since creation is the only bound that catches it.\n */\nexport async function failStuckA2ATask(\n id: string,\n processingCutoff: number,\n reason: string,\n createdAtCutoff?: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const ageCondition =\n createdAtCutoff !== undefined\n ? `AND (updated_at <= ? OR created_at <= ?)`\n : `AND updated_at <= ?`;\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n ${ageCondition}`,\n args:\n createdAtCutoff !== undefined\n ? [\n JSON.stringify(message),\n timestamp,\n now,\n id,\n processingCutoff,\n createdAtCutoff,\n ]\n : [JSON.stringify(message), timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\n/**\n * Fail a queued (submitted/working) task whose age since creation exceeds\n * `createdAtCutoff` — the dispatch-retry loop kept throttling/refiring\n * without ever reaching `processing`. Mirrors `failStuckA2ATask` but is\n * gated on the queued state set and on `created_at` (queued tasks have no\n * heartbeat, so staleness of `updated_at` isn't a meaningful signal here).\n */\nexport async function failStuckQueuedA2ATask(\n id: string,\n createdAtCutoff: number,\n reason: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')\n AND created_at <= ?`,\n args: [JSON.stringify(message), timestamp, now, id, createdAtCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function getTask(id: string): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function updateTask(\n id: string,\n update: {\n state?: TaskState;\n message?: Message;\n artifacts?: Artifact[];\n },\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n\n // Read current task\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n\n const task = taskFromRow(rows[0]);\n const now = Date.now();\n\n if (update.state) {\n task.status = {\n state: update.state,\n message: update.message ?? task.status.message,\n timestamp: new Date().toISOString(),\n };\n }\n\n if (update.message && task.history) {\n task.history.push(update.message);\n }\n\n if (update.artifacts) {\n task.artifacts = [...(task.artifacts ?? []), ...update.artifacts];\n }\n\n await client.execute({\n sql: `UPDATE a2a_tasks SET status_state = ?, status_message = ?, status_timestamp = ?, history = ?, artifacts = ?, updated_at = ? WHERE id = ?`,\n args: [\n task.status.state,\n task.status.message ? JSON.stringify(task.status.message) : null,\n task.status.timestamp,\n JSON.stringify(task.history),\n JSON.stringify(task.artifacts),\n now,\n id,\n ],\n });\n\n return task;\n}\n\nexport async function updateTaskStatusMessage(\n id: string,\n message: Message,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working', 'processing')`,\n args: [JSON.stringify(message), timestamp, now, id],\n });\n}\n\nexport async function listTasks(contextId?: string): Promise<Task[]> {\n await ensureTable();\n const client = getDbExec();\n\n if (contextId) {\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE context_id = ? ORDER BY created_at DESC`,\n args: [contextId],\n });\n return rows.map(taskFromRow);\n }\n\n const { rows } = await client.execute(\n `SELECT * FROM a2a_tasks ORDER BY created_at DESC`,\n );\n return rows.map(taskFromRow);\n}\n"]}
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\n\nimport { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport { ensureTableExists, ensureColumnExists } from \"../db/ddl-guard.js\";\nimport type { Task, Message, TaskState, Artifact } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = `\n CREATE TABLE IF NOT EXISTS a2a_tasks (\n id TEXT PRIMARY KEY,\n context_id TEXT,\n status_state TEXT NOT NULL DEFAULT 'submitted',\n status_message TEXT,\n status_timestamp TEXT NOT NULL,\n history TEXT NOT NULL DEFAULT '[]',\n artifacts TEXT NOT NULL DEFAULT '[]',\n metadata TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // PG-guard: probe information_schema before issuing DDL to avoid ACCESS\n // EXCLUSIVE lock contention in fresh background-worker processes.\n await ensureTableExists(\"a2a_tasks\", createSql);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n await ensureColumnExists(\n \"a2a_tasks\",\n \"owner_email\",\n `ALTER TABLE a2a_tasks ADD COLUMN IF NOT EXISTS owner_email TEXT`,\n );\n return;\n }\n\n // SQLite (local dev): no lock problem — keep the original behaviour.\n await client.execute(createSql);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n try {\n await client.execute(\n `ALTER TABLE a2a_tasks ADD COLUMN owner_email TEXT`,\n );\n } catch {\n // Column already exists — expected on every restart after first run.\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\nfunction taskFromRow(row: any): Task & { ownerEmail?: string | null } {\n return {\n id: row.id as string,\n contextId: (row.context_id as string) || undefined,\n status: {\n state: row.status_state as TaskState,\n message: row.status_message\n ? JSON.parse(row.status_message as string)\n : undefined,\n timestamp: row.status_timestamp as string,\n },\n history: JSON.parse(row.history as string),\n artifacts: JSON.parse(row.artifacts as string),\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n ownerEmail: (row.owner_email as string | null) ?? null,\n };\n}\n\nfunction getAffectedRowCount(result: unknown): number | undefined {\n const resultRecord = result as\n | {\n rowsAffected?: number;\n rowCount?: number;\n count?: number;\n }\n | undefined;\n return (\n resultRecord?.rowsAffected ?? resultRecord?.rowCount ?? resultRecord?.count\n );\n}\n\nexport async function createTask(\n message: Message,\n contextId?: string,\n metadata?: Record<string, unknown>,\n ownerEmail?: string | null,\n): Promise<Task> {\n await ensureTable();\n const client = getDbExec();\n const id = crypto.randomUUID();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const task: Task = {\n id,\n contextId,\n status: { state: \"submitted\", timestamp },\n history: [message],\n artifacts: [],\n metadata,\n };\n\n await client.execute({\n sql: `INSERT INTO a2a_tasks (id, context_id, status_state, status_timestamp, history, artifacts, metadata, owner_email, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n contextId ?? null,\n \"submitted\",\n timestamp,\n JSON.stringify([message]),\n \"[]\",\n metadata ? JSON.stringify(metadata) : null,\n ownerEmail ?? null,\n now,\n now,\n ],\n });\n\n return task;\n}\n\n/**\n * Fetch the verified owner email recorded against a task at creation time.\n * Returns null when the task has no owner (legacy rows or unauthenticated\n * deployments) or when the task is missing.\n *\n * Used by `handleGet` / `handleCancel` to reject IDOR access — the JWT-\n * verified caller's email must match `owner_email` to read or cancel.\n */\nexport async function getTaskOwner(id: string): Promise<string | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT owner_email FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n const ownerEmail = (rows[0] as any).owner_email;\n return typeof ownerEmail === \"string\" && ownerEmail ? ownerEmail : null;\n}\n\n/**\n * Atomically claim a task for processing. Only succeeds when the task is in\n * state 'submitted' or 'working' — flipping it to 'processing' so concurrent\n * processors can't pick it up twice. Returns the task if claimed, null if it\n * was already claimed/completed/missing.\n *\n * Used by the cross-platform async processor (`_process-task` route) to avoid\n * duplicate handler runs when retries fire.\n */\nexport async function claimA2ATaskForProcessing(\n id: string,\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'processing',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [timestamp, now, id],\n });\n const affected = getAffectedRowCount(result);\n if (affected === 0) return null;\n\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function getA2ATaskDispatchState(id: string): Promise<{\n id: string;\n statusState: string;\n metadata: Record<string, unknown> | undefined;\n updatedAt: number;\n createdAt: number;\n} | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, status_state, metadata, created_at, updated_at FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n const row = rows[0] as any;\n if (!row) return null;\n return {\n id: row.id as string,\n statusState: row.status_state as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n updatedAt: Number(row.updated_at ?? 0),\n createdAt: Number(row.created_at ?? 0),\n };\n}\n\nexport async function touchQueuedA2ATaskDispatch(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function touchProcessingA2ATask(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function resetStuckA2ATaskForRetry(\n id: string,\n processingCutoff: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'working',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\n/**\n * Fail a processing task once it is stuck. Two independent conditions can\n * trigger this, either of which alone is sufficient:\n * - `updated_at <= processingCutoff`: no heartbeat/progress touch in a\n * while — the processor likely died.\n * - `created_at <= createdAtCutoff` — a hard wall on total run time. A\n * hung await inside a still-alive process keeps `updated_at` fresh via\n * the liveness heartbeat forever, so staleness alone never trips; age\n * since creation is the only bound that catches it.\n */\nexport async function failStuckA2ATask(\n id: string,\n processingCutoff: number,\n reason: string,\n createdAtCutoff?: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const ageCondition =\n createdAtCutoff !== undefined\n ? `AND (updated_at <= ? OR created_at <= ?)`\n : `AND updated_at <= ?`;\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n ${ageCondition}`,\n args:\n createdAtCutoff !== undefined\n ? [\n JSON.stringify(message),\n timestamp,\n now,\n id,\n processingCutoff,\n createdAtCutoff,\n ]\n : [JSON.stringify(message), timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\n/**\n * Fail a queued (submitted/working) task whose age since creation exceeds\n * `createdAtCutoff` — the dispatch-retry loop kept throttling/refiring\n * without ever reaching `processing`. Mirrors `failStuckA2ATask` but is\n * gated on the queued state set and on `created_at` (queued tasks have no\n * heartbeat, so staleness of `updated_at` isn't a meaningful signal here).\n */\nexport async function failStuckQueuedA2ATask(\n id: string,\n createdAtCutoff: number,\n reason: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')\n AND created_at <= ?`,\n args: [JSON.stringify(message), timestamp, now, id, createdAtCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function getTask(id: string): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function updateTask(\n id: string,\n update: {\n state?: TaskState;\n message?: Message;\n artifacts?: Artifact[];\n },\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n\n // Read current task\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n\n const task = taskFromRow(rows[0]);\n const now = Date.now();\n\n if (update.state) {\n task.status = {\n state: update.state,\n message: update.message ?? task.status.message,\n timestamp: new Date().toISOString(),\n };\n }\n\n if (update.message && task.history) {\n task.history.push(update.message);\n }\n\n if (update.artifacts) {\n task.artifacts = [...(task.artifacts ?? []), ...update.artifacts];\n }\n\n await client.execute({\n sql: `UPDATE a2a_tasks SET status_state = ?, status_message = ?, status_timestamp = ?, history = ?, artifacts = ?, updated_at = ? WHERE id = ?`,\n args: [\n task.status.state,\n task.status.message ? JSON.stringify(task.status.message) : null,\n task.status.timestamp,\n JSON.stringify(task.history),\n JSON.stringify(task.artifacts),\n now,\n id,\n ],\n });\n\n return task;\n}\n\n/**\n * Persist the terminal result produced by the async processor, but only while\n * that processor still owns a task in `processing`. A tasks/get request may\n * fail an over-lifetime processor while its handler is still running; the\n * handler cannot be canceled reliably, so this compare-and-set is what keeps\n * its eventual completion (or error) from overwriting the timeout result.\n */\nexport async function settleProcessingA2ATask(\n id: string,\n update: {\n state: \"completed\" | \"failed\";\n message?: Message;\n artifacts?: Artifact[];\n },\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n\n const task = taskFromRow(rows[0]);\n const now = Date.now();\n task.status = {\n state: update.state,\n message: update.message ?? task.status.message,\n timestamp: new Date().toISOString(),\n };\n if (update.message && task.history) {\n task.history.push(update.message);\n }\n if (update.artifacts) {\n task.artifacts = [...(task.artifacts ?? []), ...update.artifacts];\n }\n\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = ?,\n status_message = ?,\n status_timestamp = ?,\n history = ?,\n artifacts = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'`,\n args: [\n task.status.state,\n task.status.message ? JSON.stringify(task.status.message) : null,\n task.status.timestamp,\n JSON.stringify(task.history),\n JSON.stringify(task.artifacts),\n now,\n id,\n ],\n });\n const affected = getAffectedRowCount(result);\n if (affected === 0) return null;\n return task;\n}\n\nexport async function updateTaskStatusMessage(\n id: string,\n message: Message,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working', 'processing')`,\n args: [JSON.stringify(message), timestamp, now, id],\n });\n}\n\nexport async function listTasks(contextId?: string): Promise<Task[]> {\n await ensureTable();\n const client = getDbExec();\n\n if (contextId) {\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE context_id = ? ORDER BY created_at DESC`,\n args: [contextId],\n });\n return rows.map(taskFromRow);\n }\n\n const { rows } = await client.execute(\n `SELECT * FROM a2a_tasks ORDER BY created_at DESC`,\n );\n return rows.map(taskFromRow);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/client/session-replay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/client/session-replay.ts"],"names":[],"mappings":"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"}
@@ -120,12 +120,14 @@ function getState() {
120
120
  g[SESSION_REPLAY_STATE_KEY] = {
121
121
  active: false,
122
122
  startPromise: null,
123
+ startGeneration: 0,
123
124
  replayId: null,
124
125
  startedAtMs: null,
125
126
  sequence: 0,
126
127
  queue: [],
127
128
  queuedBytes: 0,
128
129
  retryBatches: [],
130
+ transientClientErrorFailures: 0,
129
131
  flushTimer: null,
130
132
  maxDurationTimer: null,
131
133
  flushing: false,
@@ -148,10 +150,12 @@ function getState() {
148
150
  const state = g[SESSION_REPLAY_STATE_KEY];
149
151
  // Keep Vite HMR safe when an older recorder state survives a module reload.
150
152
  state.resourceNodes ??= new Map();
153
+ state.transientClientErrorFailures ??= 0;
151
154
  state.restoreIframeBridge ??= null;
152
155
  state.pendingFlushReason ??= null;
153
156
  state.pendingFlushWaiters ??= [];
154
157
  state.awaitingFullSnapshot ??= false;
158
+ state.startGeneration ??= 0;
155
159
  return state;
156
160
  }
157
161
  // The replay session record (replayId + sequence counter) lives in
@@ -983,12 +987,17 @@ class ReplayUploadHttpError extends Error {
983
987
  this.status = status;
984
988
  }
985
989
  }
986
- /** 4xx statuses where retrying the exact same batch can never succeed --
987
- * e.g. a 409 chunk-sequence/checksum conflict, or a 400 the server will
988
- * reject again. 408 (timeout) and 429 (rate limit) are excluded because a
989
- * later retry can plausibly succeed. */
990
+ /** 4xx statuses where retrying the exact same batch can never succeed.
991
+ * Keep this deliberately narrow: 401/403/404 can be temporary during auth or
992
+ * deploy transitions, so they get a small retry budget before the rejected
993
+ * episode is stopped. The budget prevents a persistent configuration failure
994
+ * from pinning retryBatches while rrweb events grow without bound. */
990
995
  function isDefinitiveReplayUploadClientError(status) {
991
- return status >= 400 && status < 500 && status !== 408 && status !== 429;
996
+ return status === 400 || status === 409 || status === 413 || status === 422;
997
+ }
998
+ const MAX_TRANSIENT_REPLAY_CLIENT_FAILURES = 3;
999
+ function isTransientReplayUploadClientError(status) {
1000
+ return status === 401 || status === 403 || status === 404;
992
1001
  }
993
1002
  async function sendReplayUpload(options, body, callbacks = {}) {
994
1003
  if (isCrossOriginReplayEndpoint(options.endpoint)) {
@@ -1223,6 +1232,7 @@ export async function flushSessionReplay(reason = "manual") {
1223
1232
  if (!reservedSequence)
1224
1233
  advanceReplaySequence(state, payload);
1225
1234
  state.automaticConflictRestartAttempted = false;
1235
+ state.transientClientErrorFailures = 0;
1226
1236
  uploaded = true;
1227
1237
  }
1228
1238
  catch (error) {
@@ -1235,8 +1245,20 @@ export async function flushSessionReplay(reason = "manual") {
1235
1245
  const rejectedStatus = error instanceof ReplayUploadHttpError ? error.status : null;
1236
1246
  const splitBatch = rejectedStatus === 413 ? splitReplayBatch(events) : null;
1237
1247
  const isUnsplittableOversizedBatch = rejectedStatus === 413 && splitBatch === null;
1248
+ const isTransientClientError = rejectedStatus !== null &&
1249
+ isTransientReplayUploadClientError(rejectedStatus);
1250
+ if (isTransientClientError) {
1251
+ state.transientClientErrorFailures += 1;
1252
+ }
1253
+ else {
1254
+ state.transientClientErrorFailures = 0;
1255
+ }
1256
+ const exhaustedTransientClientRetries = isTransientClientError &&
1257
+ state.transientClientErrorFailures >=
1258
+ MAX_TRANSIENT_REPLAY_CLIENT_FAILURES;
1238
1259
  const isDefinitiveClientError = error instanceof ReplayUploadHttpError &&
1239
- isDefinitiveReplayUploadClientError(error.status) &&
1260
+ (isDefinitiveReplayUploadClientError(error.status) ||
1261
+ exhaustedTransientClientRetries) &&
1240
1262
  !splitBatch &&
1241
1263
  !isUnsplittableOversizedBatch;
1242
1264
  if (splitBatch) {
@@ -1382,6 +1404,21 @@ export async function flushSessionReplay(reason = "manual") {
1382
1404
  * on internal option shapes continuing to round-trip through the public API.
1383
1405
  */
1384
1406
  async function restartSessionReplayAfterConflict(state, options, sessionId) {
1407
+ // Share the public-start mutex. A consumer may call start in the await gap
1408
+ // after the rejected recorder stops; both paths must converge on one rrweb
1409
+ // instance rather than racing two fresh identities.
1410
+ if (state.startPromise)
1411
+ return state.startPromise;
1412
+ const startGeneration = ++state.startGeneration;
1413
+ let startPromise;
1414
+ startPromise = restartSessionReplayAfterConflictInternal(state, options, sessionId, startGeneration).finally(() => {
1415
+ if (state.startPromise === startPromise)
1416
+ state.startPromise = null;
1417
+ });
1418
+ state.startPromise = startPromise;
1419
+ return startPromise;
1420
+ }
1421
+ async function restartSessionReplayAfterConflictInternal(state, options, sessionId, startGeneration) {
1385
1422
  if (options.shouldStart && !options.shouldStart()) {
1386
1423
  return { started: false, reason: "disabled", sessionId, sampled: true };
1387
1424
  }
@@ -1402,7 +1439,7 @@ async function restartSessionReplayAfterConflict(state, options, sessionId) {
1402
1439
  sampled: true,
1403
1440
  };
1404
1441
  }
1405
- return startSessionReplayRecorder(state, options, sessionId, true, initialProperties);
1442
+ return startSessionReplayRecorder(state, options, sessionId, true, initialProperties, startGeneration);
1406
1443
  }
1407
1444
  function installUrlMonitor(state) {
1408
1445
  if (!state.options || state.restoreUrlMonitor)
@@ -2178,8 +2215,13 @@ export async function startSessionReplay(options = {}) {
2178
2215
  }
2179
2216
  if (state.startPromise)
2180
2217
  return state.startPromise;
2218
+ // This is a new caller-initiated recording episode. A prior episode's
2219
+ // conflict-loop guard must not prevent this one from recovering once.
2220
+ state.automaticConflictRestartAttempted = false;
2221
+ state.transientClientErrorFailures = 0;
2222
+ const startGeneration = ++state.startGeneration;
2181
2223
  let startPromise;
2182
- startPromise = startSessionReplayRecorder(state, normalized, sessionId, sampled, initialProperties).finally(() => {
2224
+ startPromise = startSessionReplayRecorder(state, normalized, sessionId, sampled, initialProperties, startGeneration).finally(() => {
2183
2225
  if (state.startPromise === startPromise) {
2184
2226
  state.startPromise = null;
2185
2227
  }
@@ -2187,7 +2229,7 @@ export async function startSessionReplay(options = {}) {
2187
2229
  state.startPromise = startPromise;
2188
2230
  return startPromise;
2189
2231
  }
2190
- async function startSessionReplayRecorder(state, normalized, sessionId, sampled, initialProperties) {
2232
+ async function startSessionReplayRecorder(state, normalized, sessionId, sampled, initialProperties, startGeneration) {
2191
2233
  if (state.active && state.replayId) {
2192
2234
  return {
2193
2235
  started: true,
@@ -2204,6 +2246,9 @@ async function startSessionReplayRecorder(state, normalized, sessionId, sampled,
2204
2246
  catch {
2205
2247
  return { started: false, reason: "import-failed", sessionId, sampled };
2206
2248
  }
2249
+ if (state.startGeneration !== startGeneration) {
2250
+ return { started: false, reason: "disabled", sessionId, sampled };
2251
+ }
2207
2252
  if (normalized.shouldStart && !normalized.shouldStart()) {
2208
2253
  return { started: false, reason: "disabled", sessionId, sampled };
2209
2254
  }
@@ -2232,6 +2277,19 @@ async function startSessionReplayRecorder(state, normalized, sessionId, sampled,
2232
2277
  };
2233
2278
  }
2234
2279
  }
2280
+ // stopSessionReplay may be called while the duplicate-tab probe is waiting.
2281
+ // Recheck both cancellation and the caller's live eligibility before rrweb
2282
+ // is activated so a deferred start cannot escape a route/auth teardown.
2283
+ if (state.startGeneration !== startGeneration ||
2284
+ (normalized.shouldStart && !normalized.shouldStart())) {
2285
+ try {
2286
+ replayChannel?.close();
2287
+ }
2288
+ catch {
2289
+ // best-effort cleanup
2290
+ }
2291
+ return { started: false, reason: "disabled", sessionId, sampled };
2292
+ }
2235
2293
  state.options = normalized;
2236
2294
  state.replayId = replaySession.replayId;
2237
2295
  state.startedAtMs = replaySession.startedAtMs;
@@ -2328,6 +2386,10 @@ async function startSessionReplayRecorder(state, normalized, sessionId, sampled,
2328
2386
  }
2329
2387
  export async function stopSessionReplay(reason = "manual") {
2330
2388
  const state = getState();
2389
+ // Invalidate an import/probe that has not set `active` yet. Without this,
2390
+ // stop during the duplicated-tab claim window was a no-op and rrweb started
2391
+ // after the caller believed recording had been disabled.
2392
+ state.startGeneration += 1;
2331
2393
  if (!state.active)
2332
2394
  return;
2333
2395
  // Restore console/fetch/XHR before tearing down the recorder: the restore