@agent-native/core 0.94.2 → 0.94.3

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 (38) hide show
  1. package/corpus/core/CHANGELOG.md +8 -0
  2. package/corpus/core/package.json +1 -1
  3. package/corpus/core/src/a2a/artifact-response.ts +154 -1
  4. package/corpus/core/src/integrations/a2a-continuation-processor.ts +118 -31
  5. package/corpus/core/src/integrations/a2a-continuations-store.ts +165 -7
  6. package/corpus/core/src/integrations/adapters/slack.ts +77 -7
  7. package/corpus/core/src/integrations/types.ts +30 -0
  8. package/corpus/core/src/integrations/webhook-handler.ts +54 -18
  9. package/corpus/core/src/scripts/call-agent.ts +1 -0
  10. package/corpus/core/src/server/request-context.ts +2 -0
  11. package/dist/a2a/artifact-response.d.ts.map +1 -1
  12. package/dist/a2a/artifact-response.js +127 -1
  13. package/dist/a2a/artifact-response.js.map +1 -1
  14. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  15. package/dist/integrations/a2a-continuation-processor.js +76 -21
  16. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  17. package/dist/integrations/a2a-continuations-store.d.ts +4 -1
  18. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  19. package/dist/integrations/a2a-continuations-store.js +130 -6
  20. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  21. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  22. package/dist/integrations/adapters/slack.js +56 -7
  23. package/dist/integrations/adapters/slack.js.map +1 -1
  24. package/dist/integrations/types.d.ts +25 -0
  25. package/dist/integrations/types.d.ts.map +1 -1
  26. package/dist/integrations/types.js.map +1 -1
  27. package/dist/integrations/webhook-handler.js +54 -16
  28. package/dist/integrations/webhook-handler.js.map +1 -1
  29. package/dist/resources/handlers.d.ts +2 -2
  30. package/dist/scripts/call-agent.d.ts.map +1 -1
  31. package/dist/scripts/call-agent.js +1 -0
  32. package/dist/scripts/call-agent.js.map +1 -1
  33. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  34. package/dist/server/request-context.d.ts +2 -0
  35. package/dist/server/request-context.d.ts.map +1 -1
  36. package/dist/server/request-context.js.map +1 -1
  37. package/dist/server/transcribe-voice.d.ts +1 -1
  38. package/package.json +1 -1
@@ -93,6 +93,7 @@ async function processClaimedContinuation(continuation, options) {
93
93
  await failA2AContinuation(continuation.id, `Unknown platform: ${continuation.platform}`);
94
94
  return;
95
95
  }
96
+ const progress = await resumeA2AContinuationProgress(continuation, adapter);
96
97
  const auth = await signContinuationToken(continuation);
97
98
  const client = new A2AClient(continuation.agentUrl, auth.apiKey, {
98
99
  requestTimeoutMs: POLL_REQUEST_TIMEOUT_MS,
@@ -105,33 +106,29 @@ async function processClaimedContinuation(continuation, options) {
105
106
  task = await client.getTask(continuation.a2aTaskId);
106
107
  if (TERMINAL_STATES.has(task.status.state))
107
108
  break;
109
+ await reportA2AContinuationProgress(continuation, progress, task);
108
110
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
109
111
  }
110
112
  }
111
113
  catch (err) {
112
114
  if (isTransientA2APollError(err)) {
113
115
  if (shouldStopPollingRemoteTask(continuation)) {
114
- await notifyAndFailA2AContinuation(continuation, adapter, remotePollFailureReason(continuation));
116
+ await notifyAndFailA2AContinuation(continuation, adapter, remotePollFailureReason(continuation), progress);
115
117
  return;
116
118
  }
117
119
  await rescheduleAndRedispatchA2AContinuation(continuation.id);
118
120
  return;
119
121
  }
120
122
  if (continuation.attempts >= MAX_ATTEMPTS) {
121
- await notifyAndFailA2AContinuation(continuation, adapter, err instanceof Error ? err.message : String(err));
123
+ await notifyAndFailA2AContinuation(continuation, adapter, err instanceof Error ? err.message : String(err), progress);
122
124
  return;
123
125
  }
124
126
  await rescheduleAndRedispatchA2AContinuation(continuation.id);
125
127
  return;
126
128
  }
127
129
  if (!task || !TERMINAL_STATES.has(task.status.state)) {
128
- const recoverableArtifactText = extractRecoverableArtifactText(task);
129
- if (recoverableArtifactText) {
130
- await deliverAndCompleteA2AContinuation(continuation, adapter, formatContinuationArtifactText(recoverableArtifactText, continuation.agentUrl));
131
- return;
132
- }
133
130
  if (shouldStopPollingRemoteTask(continuation)) {
134
- await notifyAndFailA2AContinuation(continuation, adapter, remotePollFailureReason(continuation));
131
+ await notifyAndFailA2AContinuation(continuation, adapter, remotePollFailureReason(continuation), progress);
135
132
  return;
136
133
  }
137
134
  await rescheduleAndRedispatchA2AContinuation(continuation.id);
@@ -140,15 +137,48 @@ async function processClaimedContinuation(continuation, options) {
140
137
  if (task.status.state !== "completed") {
141
138
  const reason = extractTaskText(task) ||
142
139
  `Remote A2A task ${continuation.a2aTaskId} ended with state ${task.status.state}`;
143
- await notifyAndFailA2AContinuation(continuation, adapter, reason);
140
+ await notifyAndFailA2AContinuation(continuation, adapter, reason, progress);
144
141
  return;
145
142
  }
146
143
  const text = formatContinuationArtifactText(extractTaskText(task), continuation.agentUrl);
147
144
  if (!text.trim()) {
148
- await notifyAndFailA2AContinuation(continuation, adapter, `Remote A2A task ${continuation.a2aTaskId} completed without text`);
145
+ await notifyAndFailA2AContinuation(continuation, adapter, `Remote A2A task ${continuation.a2aTaskId} completed without text`, progress);
149
146
  return;
150
147
  }
151
- await deliverAndCompleteA2AContinuation(continuation, adapter, text);
148
+ await deliverAndCompleteA2AContinuation(continuation, adapter, text, progress);
149
+ }
150
+ async function resumeA2AContinuationProgress(continuation, adapter) {
151
+ if (!continuation.progressRef || !adapter.resumeRunProgress)
152
+ return null;
153
+ try {
154
+ const progress = await adapter.resumeRunProgress(continuation.incoming, continuation.progressRef);
155
+ if (!progress)
156
+ return null;
157
+ await progress.onEvent({
158
+ type: "agent_call_progress",
159
+ agent: continuation.agentName,
160
+ state: "working",
161
+ elapsedSeconds: Math.max(0, Math.round((Date.now() - continuation.createdAt) / 1_000)),
162
+ detail: "Continuing in the background",
163
+ });
164
+ return progress;
165
+ }
166
+ catch {
167
+ // A continuation still has a normal reply fallback. Do not log the
168
+ // opaque provider reference or the inbound message payload.
169
+ return null;
170
+ }
171
+ }
172
+ async function reportA2AContinuationProgress(continuation, progress, task) {
173
+ if (!progress)
174
+ return;
175
+ await progress.onEvent({
176
+ type: "agent_call_progress",
177
+ agent: continuation.agentName,
178
+ state: task.status.state,
179
+ elapsedSeconds: Math.max(0, Math.round((Date.now() - continuation.createdAt) / 1_000)),
180
+ detail: "Still working on the delegated request",
181
+ });
152
182
  }
153
183
  async function waitForContinuationDue(continuationId) {
154
184
  const continuation = await getA2AContinuation(continuationId);
@@ -167,25 +197,27 @@ async function waitForContinuationDue(continuationId) {
167
197
  await sleep(waitMs);
168
198
  return true;
169
199
  }
170
- async function notifyAndFailA2AContinuation(continuation, adapter, reason) {
200
+ async function notifyAndFailA2AContinuation(continuation, adapter, reason, progress = null) {
171
201
  const deliveryContinuation = await claimA2AContinuationDelivery(continuation.id);
172
202
  if (!deliveryContinuation)
173
203
  return;
174
204
  const message = formatContinuationFailureMessage(deliveryContinuation, reason);
175
205
  try {
176
- await withTimeout(adapter.sendResponse(adapter.formatAgentResponse(message), deliveryContinuation.incoming, { placeholderRef: deliveryContinuation.placeholderRef ?? undefined }), PLATFORM_SEND_TIMEOUT_MS, `${deliveryContinuation.platform} failure notification timed out`);
206
+ const outgoing = adapter.formatAgentResponse(message);
207
+ await withTimeout(deliverA2AContinuationResponse(adapter, deliveryContinuation, outgoing, progress, "error"), PLATFORM_SEND_TIMEOUT_MS, `${deliveryContinuation.platform} failure notification timed out`);
177
208
  }
178
209
  catch (err) {
179
210
  console.error(`[integrations] Failed to notify ${deliveryContinuation.platform} about failed A2A continuation ${deliveryContinuation.id}:`, err);
180
211
  }
181
212
  await failA2AContinuation(deliveryContinuation.id, reason);
182
213
  }
183
- async function deliverAndCompleteA2AContinuation(continuation, adapter, text) {
214
+ async function deliverAndCompleteA2AContinuation(continuation, adapter, text, progress = null) {
184
215
  const deliveryContinuation = await claimA2AContinuationDelivery(continuation.id);
185
216
  if (!deliveryContinuation)
186
217
  return;
187
218
  try {
188
- await withTimeout(adapter.sendResponse(adapter.formatAgentResponse(text), deliveryContinuation.incoming, { placeholderRef: deliveryContinuation.placeholderRef ?? undefined }), PLATFORM_SEND_TIMEOUT_MS, `${deliveryContinuation.platform} response delivery timed out`);
219
+ const outgoing = adapter.formatAgentResponse(text);
220
+ await withTimeout(deliverA2AContinuationResponse(adapter, deliveryContinuation, outgoing, progress, "done"), PLATFORM_SEND_TIMEOUT_MS, `${deliveryContinuation.platform} response delivery timed out`);
189
221
  }
190
222
  catch (err) {
191
223
  if (deliveryContinuation.attempts >= MAX_ATTEMPTS) {
@@ -197,6 +229,35 @@ async function deliverAndCompleteA2AContinuation(continuation, adapter, text) {
197
229
  }
198
230
  await completeAfterSuccessfulDelivery(deliveryContinuation);
199
231
  }
232
+ async function deliverA2AContinuationResponse(adapter, continuation, message, progress, status) {
233
+ if (progress) {
234
+ try {
235
+ await progress.onEvent({
236
+ type: "agent_call",
237
+ agent: continuation.agentName,
238
+ status,
239
+ });
240
+ await progress.complete(message);
241
+ return;
242
+ }
243
+ catch {
244
+ // A resumed Slack stream can no longer be finalized (for example when
245
+ // chat.stopStream rejects). Preserve the final answer with the same
246
+ // thread reply fallback used by the initial webhook run. Also ask the
247
+ // adapter to terminate the native stream: otherwise Slack can keep the
248
+ // task card in its working state after the thread fallback succeeds.
249
+ try {
250
+ await progress.fail?.("I couldn't update the live response, but I posted the final result in this thread.");
251
+ }
252
+ catch {
253
+ // The thread reply below is still the authoritative final answer.
254
+ }
255
+ }
256
+ }
257
+ await adapter.sendResponse(message, continuation.incoming, {
258
+ placeholderRef: continuation.placeholderRef ?? undefined,
259
+ });
260
+ }
200
261
  async function rescheduleAndRedispatchA2AContinuation(continuationId) {
201
262
  await rescheduleA2AContinuation(continuationId, RESCHEDULE_DELAY_MS);
202
263
  await dispatchA2AContinuation(continuationId).catch((err) => {
@@ -344,12 +405,6 @@ function extractTaskText(task) {
344
405
  .map((part) => part.text)
345
406
  .join("\n");
346
407
  }
347
- function extractRecoverableArtifactText(task) {
348
- if (!task?.status.message?.metadata?.agentNativeRecoverableArtifacts) {
349
- return "";
350
- }
351
- return extractTaskText(task);
352
- }
353
408
  function formatContinuationArtifactText(text, agentUrl) {
354
409
  const expandedText = expandRelativeUrls(text, agentUrl);
355
410
  return appendA2AArtifactLinks(expandedText, [{ tool: "call-agent", result: expandedText }], { baseUrl: resolveArtifactBaseUrl() });
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-continuation-processor.js","sourceRoot":"","sources":["../../src/integrations/a2a-continuation-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendA2AArtifactLinks } from \"../a2a/artifact-response.js\";\nimport { A2AClient, signA2AToken } from \"../a2a/client.js\";\nimport type { Task } from \"../a2a/types.js\";\nimport {\n formatLlmCredentialErrorMessage,\n isLlmCredentialError,\n} from \"../agent/engine/credential-errors.js\";\nimport { withConfiguredAppBasePath } from \"../server/app-base-path.js\";\nimport { FRAMEWORK_ROUTE_PREFIX } from \"../server/core-routes-plugin.js\";\nimport {\n claimA2AContinuation,\n claimA2AContinuationDelivery,\n claimDueA2AContinuations,\n completeA2AContinuation,\n failA2AContinuation,\n getA2AContinuation,\n rescheduleA2AContinuation,\n type A2AContinuation,\n} from \"./a2a-continuations-store.js\";\nimport { signInternalToken } from \"./internal-token.js\";\nimport type { PlatformAdapter } from \"./types.js\";\n\nconst PROCESSOR_PATH = `${FRAMEWORK_ROUTE_PREFIX}/integrations/process-a2a-continuation`;\nconst TERMINAL_STATES = new Set([\"completed\", \"failed\", \"canceled\"]);\nconst MAX_ATTEMPTS = 30;\nconst MAX_REMOTE_WORK_MS = 20 * 60_000;\n// Re-dispatch continuations after a short delay. Serverless hosts do not keep\n// in-memory interval sweepers alive between requests, so delayed self-dispatch\n// is the portable retry mechanism.\nconst RESCHEDULE_DELAY_MS = 20_000;\nconst MAX_PRE_CLAIM_WAIT_MS = 25_000;\nconst POLL_INTERVAL_MS = 2_000;\nconst PROCESSOR_WAIT_MS = 10_000;\nconst POLL_REQUEST_TIMEOUT_MS = 8_000;\nconst PLATFORM_SEND_TIMEOUT_MS = 12_000;\nconst DISPATCH_SETTLE_WAIT_MS = 2_000;\nconst COMPLETE_AFTER_DELIVERY_ATTEMPTS = 3;\n\nexport async function dispatchA2AContinuation(\n continuationId: string,\n webhookBaseUrl?: string,\n): Promise<void> {\n const baseUrl =\n webhookBaseUrl ||\n process.env.WEBHOOK_BASE_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n `http://localhost:${process.env.PORT || 3000}`;\n\n const url = `${withConfiguredAppBasePath(baseUrl)}${PROCESSOR_PATH}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n try {\n headers[\"Authorization\"] = `Bearer ${signInternalToken(continuationId)}`;\n } catch (err) {\n if (process.env.NODE_ENV === \"production\") {\n console.error(\n `[integrations] Refusing to dispatch A2A continuation ${continuationId} — A2A_SECRET not configured.`,\n );\n return;\n }\n if (err instanceof Error && !/A2A_SECRET/i.test(err.message)) {\n console.error(\n `[integrations] signInternalToken failed unexpectedly for ${continuationId}:`,\n err,\n );\n }\n }\n\n const dispatchPromise = fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ continuationId }),\n })\n .then(async (response) => {\n if (!response.ok) {\n await logFailedDispatchResponse(continuationId, response);\n }\n })\n .catch((err) => {\n console.error(\n `[integrations] Failed to dispatch A2A continuation ${continuationId}:`,\n err,\n );\n });\n\n await Promise.race([\n dispatchPromise,\n new Promise<void>((resolve) =>\n setTimeout(resolve, DISPATCH_SETTLE_WAIT_MS),\n ),\n ]);\n}\n\nasync function logFailedDispatchResponse(\n continuationId: string,\n response: Response,\n): Promise<void> {\n let body = \"\";\n try {\n body = await response.text();\n } catch {}\n\n const trimmedBody = body.trim();\n console.error(\n `[integrations] A2A continuation ${continuationId} processor dispatch returned HTTP ` +\n `${response.status}${response.statusText ? ` ${response.statusText}` : \"\"}` +\n `${trimmedBody ? `: ${trimmedBody.slice(0, 500)}` : \"\"}`,\n );\n}\n\nexport async function processA2AContinuationById(\n continuationId: string,\n options: { adapters: Map<string, PlatformAdapter> },\n): Promise<void> {\n const shouldClaim = await waitForContinuationDue(continuationId);\n if (!shouldClaim) return;\n const continuation = await claimA2AContinuation(continuationId);\n if (!continuation) return;\n await processClaimedContinuation(continuation, options);\n}\n\nexport async function processDueA2AContinuations(options: {\n adapters: Map<string, PlatformAdapter>;\n limit?: number;\n}): Promise<void> {\n const continuations = await claimDueA2AContinuations(options.limit ?? 5);\n for (const continuation of continuations) {\n await processClaimedContinuation(continuation, options).catch((err) =>\n console.error(\n `[integrations] A2A continuation ${continuation.id} failed:`,\n err,\n ),\n );\n }\n}\n\nasync function processClaimedContinuation(\n continuation: A2AContinuation,\n options: { adapters: Map<string, PlatformAdapter> },\n): Promise<void> {\n const adapter = options.adapters.get(continuation.platform);\n if (!adapter) {\n await failA2AContinuation(\n continuation.id,\n `Unknown platform: ${continuation.platform}`,\n );\n return;\n }\n\n const auth = await signContinuationToken(continuation);\n const client = new A2AClient(continuation.agentUrl, auth.apiKey, {\n requestTimeoutMs: POLL_REQUEST_TIMEOUT_MS,\n ...(auth.apiKeyFallbacks ? { fallbackApiKeys: auth.apiKeyFallbacks } : {}),\n });\n const deadline = Date.now() + PROCESSOR_WAIT_MS;\n let task: Task | null = null;\n\n try {\n while (Date.now() < deadline) {\n task = await client.getTask(continuation.a2aTaskId);\n if (TERMINAL_STATES.has(task.status.state)) break;\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n }\n } catch (err) {\n if (isTransientA2APollError(err)) {\n if (shouldStopPollingRemoteTask(continuation)) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n remotePollFailureReason(continuation),\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n if (continuation.attempts >= MAX_ATTEMPTS) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n err instanceof Error ? err.message : String(err),\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n\n if (!task || !TERMINAL_STATES.has(task.status.state)) {\n const recoverableArtifactText = extractRecoverableArtifactText(task);\n if (recoverableArtifactText) {\n await deliverAndCompleteA2AContinuation(\n continuation,\n adapter,\n formatContinuationArtifactText(\n recoverableArtifactText,\n continuation.agentUrl,\n ),\n );\n return;\n }\n\n if (shouldStopPollingRemoteTask(continuation)) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n remotePollFailureReason(continuation),\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n\n if (task.status.state !== \"completed\") {\n const reason =\n extractTaskText(task) ||\n `Remote A2A task ${continuation.a2aTaskId} ended with state ${task.status.state}`;\n await notifyAndFailA2AContinuation(continuation, adapter, reason);\n return;\n }\n\n const text = formatContinuationArtifactText(\n extractTaskText(task),\n continuation.agentUrl,\n );\n if (!text.trim()) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n `Remote A2A task ${continuation.a2aTaskId} completed without text`,\n );\n return;\n }\n\n await deliverAndCompleteA2AContinuation(continuation, adapter, text);\n}\n\nasync function waitForContinuationDue(\n continuationId: string,\n): Promise<boolean> {\n const continuation = await getA2AContinuation(continuationId);\n if (!continuation) return false;\n if (continuation.status === \"completed\" || continuation.status === \"failed\") {\n return false;\n }\n if (continuation.status !== \"pending\") return true;\n\n const waitMs = continuation.nextCheckAt - Date.now();\n if (waitMs <= 0) return true;\n\n if (waitMs > MAX_PRE_CLAIM_WAIT_MS) return false;\n\n await sleep(waitMs);\n return true;\n}\n\nasync function notifyAndFailA2AContinuation(\n continuation: A2AContinuation,\n adapter: PlatformAdapter,\n reason: string,\n): Promise<void> {\n const deliveryContinuation = await claimA2AContinuationDelivery(\n continuation.id,\n );\n if (!deliveryContinuation) return;\n\n const message = formatContinuationFailureMessage(\n deliveryContinuation,\n reason,\n );\n try {\n await withTimeout(\n adapter.sendResponse(\n adapter.formatAgentResponse(message),\n deliveryContinuation.incoming,\n { placeholderRef: deliveryContinuation.placeholderRef ?? undefined },\n ),\n PLATFORM_SEND_TIMEOUT_MS,\n `${deliveryContinuation.platform} failure notification timed out`,\n );\n } catch (err) {\n console.error(\n `[integrations] Failed to notify ${deliveryContinuation.platform} about failed A2A continuation ${deliveryContinuation.id}:`,\n err,\n );\n }\n\n await failA2AContinuation(deliveryContinuation.id, reason);\n}\n\nasync function deliverAndCompleteA2AContinuation(\n continuation: A2AContinuation,\n adapter: PlatformAdapter,\n text: string,\n): Promise<void> {\n const deliveryContinuation = await claimA2AContinuationDelivery(\n continuation.id,\n );\n if (!deliveryContinuation) return;\n\n try {\n await withTimeout(\n adapter.sendResponse(\n adapter.formatAgentResponse(text),\n deliveryContinuation.incoming,\n { placeholderRef: deliveryContinuation.placeholderRef ?? undefined },\n ),\n PLATFORM_SEND_TIMEOUT_MS,\n `${deliveryContinuation.platform} response delivery timed out`,\n );\n } catch (err) {\n if (deliveryContinuation.attempts >= MAX_ATTEMPTS) {\n await failA2AContinuation(\n deliveryContinuation.id,\n err instanceof Error ? err.message : String(err),\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(deliveryContinuation.id);\n return;\n }\n\n await completeAfterSuccessfulDelivery(deliveryContinuation);\n}\n\nasync function rescheduleAndRedispatchA2AContinuation(\n continuationId: string,\n): Promise<void> {\n await rescheduleA2AContinuation(continuationId, RESCHEDULE_DELAY_MS);\n await dispatchA2AContinuation(continuationId).catch((err) => {\n console.error(\n `[integrations] Failed to redispatch A2A continuation ${continuationId}:`,\n err,\n );\n });\n}\n\nasync function completeAfterSuccessfulDelivery(\n continuation: A2AContinuation,\n): Promise<void> {\n let lastError: unknown;\n for (let attempt = 0; attempt < COMPLETE_AFTER_DELIVERY_ATTEMPTS; attempt++) {\n try {\n await completeA2AContinuation(continuation.id);\n return;\n } catch (err) {\n lastError = err;\n }\n }\n\n console.error(\n `[integrations] ${continuation.platform} accepted A2A continuation ${continuation.id}, ` +\n \"but marking it completed failed. Leaving it in delivering for stale-delivery recovery.\",\n lastError,\n );\n}\n\nfunction formatContinuationFailureMessage(\n continuation: A2AContinuation,\n reason: string,\n): string {\n if (isLlmCredentialError(reason)) {\n return formatLlmCredentialErrorMessage({\n agentName: continuation.agentName,\n });\n }\n\n return `The ${continuation.agentName} agent could not finish this request: ${sanitizeFailureReason(\n reason,\n )}`;\n}\n\nfunction isRemoteWorkExpired(continuation: A2AContinuation): boolean {\n return Date.now() - continuation.createdAt >= MAX_REMOTE_WORK_MS;\n}\n\nfunction shouldStopPollingRemoteTask(continuation: A2AContinuation): boolean {\n return (\n continuation.attempts >= MAX_ATTEMPTS || isRemoteWorkExpired(continuation)\n );\n}\n\nfunction isTransientA2APollError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n if (err.name === \"AbortError\") return true;\n return /operation was aborted|aborted|timed out|timeout|Invalid or expired A2A token|A2A request failed \\((?:401|508)\\)/i.test(\n err.message,\n );\n}\n\nfunction remotePollFailureReason(continuation: A2AContinuation): string {\n if (isRemoteWorkExpired(continuation)) {\n return `Timed out polling the ${continuation.agentName} A2A task ${continuation.a2aTaskId} after ${Math.round(\n MAX_REMOTE_WORK_MS / 60_000,\n )} minutes. The downstream agent did not return a final result.`;\n }\n\n return `Timed out polling the ${continuation.agentName} A2A task ${continuation.a2aTaskId} after ${MAX_ATTEMPTS} attempts. The downstream agent did not return a final result.`;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), timeoutMs);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction sanitizeFailureReason(reason: string): string {\n const oneLine = reason.replace(/\\s+/g, \" \").trim();\n const withoutEnvNames = oneLine.replace(\n /\\b[A-Z][A-Z0-9_]*(?:API_KEY|PRIVATE_KEY|SECRET|TOKEN)\\b/g,\n \"a required credential\",\n );\n return (\n withoutEnvNames.slice(0, 500) ||\n \"the downstream agent returned an empty error\"\n );\n}\n\nasync function signContinuationToken(\n continuation: A2AContinuation,\n): Promise<{ apiKey?: string; apiKeyFallbacks?: string[] }> {\n if (continuation.a2aAuthToken === \"\") {\n return {};\n }\n\n const storedToken = continuation.a2aAuthToken;\n if (storedToken && !isLikelyJwt(storedToken)) return { apiKey: storedToken };\n\n const freshTokens = await signFreshContinuationTokens(continuation);\n if (freshTokens.length > 0) {\n return {\n apiKey: freshTokens[0],\n ...(freshTokens.length > 1\n ? { apiKeyFallbacks: freshTokens.slice(1) }\n : {}),\n };\n }\n if (!storedToken) return {};\n\n // Older continuations may have persisted the initial short-lived JWT. Avoid\n // replaying it forever after expiry; opaque legacy bearer keys can still be\n // reused because we cannot re-mint those.\n if (isLikelyJwt(storedToken)) return {};\n return { apiKey: storedToken };\n}\n\nasync function signFreshContinuationTokens(\n continuation: A2AContinuation,\n): Promise<string[]> {\n let orgDomain: string | undefined;\n let orgSecret: string | undefined;\n if (continuation.orgId) {\n try {\n const { getOrgDomain, getOrgA2ASecret } =\n await import(\"../org/context.js\");\n orgDomain = (await getOrgDomain(continuation.orgId)) ?? undefined;\n orgSecret = (await getOrgA2ASecret(continuation.orgId)) ?? undefined;\n } catch {}\n }\n\n if (!continuation.ownerEmail || !(orgSecret || process.env.A2A_SECRET)) {\n return [];\n }\n\n const tokens: string[] = [];\n const add = (token: string | undefined) => {\n if (token && !tokens.includes(token)) tokens.push(token);\n };\n\n if (process.env.A2A_SECRET?.trim()) {\n try {\n add(\n await signA2AToken(continuation.ownerEmail, orgDomain, orgSecret, {\n expiresIn: \"30m\",\n preferGlobalSecret: true,\n }),\n );\n } catch {}\n }\n if (orgSecret) {\n try {\n add(\n await signA2AToken(continuation.ownerEmail, orgDomain, orgSecret, {\n expiresIn: \"30m\",\n preferGlobalSecret: false,\n }),\n );\n } catch {}\n }\n return tokens;\n}\n\nfunction isLikelyJwt(token: string): boolean {\n return token.split(\".\").length === 3;\n}\n\nfunction extractTaskText(task: Task): string {\n const parts = task.status.message?.parts ?? [];\n return parts\n .filter((part): part is { type: \"text\"; text: string } => {\n return part.type === \"text\" && typeof part.text === \"string\";\n })\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\nfunction extractRecoverableArtifactText(task: Task | null): string {\n if (!task?.status.message?.metadata?.agentNativeRecoverableArtifacts) {\n return \"\";\n }\n return extractTaskText(task);\n}\n\nfunction formatContinuationArtifactText(\n text: string,\n agentUrl: string,\n): string {\n const expandedText = expandRelativeUrls(text, agentUrl);\n return appendA2AArtifactLinks(\n expandedText,\n [{ tool: \"call-agent\", result: expandedText }],\n { baseUrl: resolveArtifactBaseUrl() },\n );\n}\n\nfunction resolveArtifactBaseUrl(): string | undefined {\n const baseUrl =\n process.env.APP_URL || process.env.URL || process.env.DEPLOY_URL;\n return baseUrl ? withConfiguredAppBasePath(baseUrl) : undefined;\n}\n\nfunction expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = publicAgentBaseUrl(agentUrl);\n return text.replace(\n /(^|[\\s([<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n\nfunction publicAgentBaseUrl(agentUrl: string): string {\n try {\n const url = new URL(agentUrl);\n const routeIndex = url.pathname.indexOf(FRAMEWORK_ROUTE_PREFIX);\n url.pathname =\n routeIndex >= 0\n ? url.pathname.slice(0, routeIndex) || \"/\"\n : url.pathname.replace(/\\/+$/, \"\") || \"/\";\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/$/, \"\");\n } catch {\n return agentUrl.replace(/\\/$/, \"\");\n }\n}\n"]}
1
+ {"version":3,"file":"a2a-continuation-processor.js","sourceRoot":"","sources":["../../src/integrations/a2a-continuation-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendA2AArtifactLinks } from \"../a2a/artifact-response.js\";\nimport { A2AClient, signA2AToken } from \"../a2a/client.js\";\nimport type { Task } from \"../a2a/types.js\";\nimport {\n formatLlmCredentialErrorMessage,\n isLlmCredentialError,\n} from \"../agent/engine/credential-errors.js\";\nimport { withConfiguredAppBasePath } from \"../server/app-base-path.js\";\nimport { FRAMEWORK_ROUTE_PREFIX } from \"../server/core-routes-plugin.js\";\nimport {\n claimA2AContinuation,\n claimA2AContinuationDelivery,\n claimDueA2AContinuations,\n completeA2AContinuation,\n failA2AContinuation,\n getA2AContinuation,\n rescheduleA2AContinuation,\n type A2AContinuation,\n} from \"./a2a-continuations-store.js\";\nimport { signInternalToken } from \"./internal-token.js\";\nimport type {\n OutgoingMessage,\n PlatformAdapter,\n PlatformRunProgress,\n} from \"./types.js\";\n\nconst PROCESSOR_PATH = `${FRAMEWORK_ROUTE_PREFIX}/integrations/process-a2a-continuation`;\nconst TERMINAL_STATES = new Set([\"completed\", \"failed\", \"canceled\"]);\nconst MAX_ATTEMPTS = 30;\nconst MAX_REMOTE_WORK_MS = 20 * 60_000;\n// Re-dispatch continuations after a short delay. Serverless hosts do not keep\n// in-memory interval sweepers alive between requests, so delayed self-dispatch\n// is the portable retry mechanism.\nconst RESCHEDULE_DELAY_MS = 20_000;\nconst MAX_PRE_CLAIM_WAIT_MS = 25_000;\nconst POLL_INTERVAL_MS = 2_000;\nconst PROCESSOR_WAIT_MS = 10_000;\nconst POLL_REQUEST_TIMEOUT_MS = 8_000;\nconst PLATFORM_SEND_TIMEOUT_MS = 12_000;\nconst DISPATCH_SETTLE_WAIT_MS = 2_000;\nconst COMPLETE_AFTER_DELIVERY_ATTEMPTS = 3;\n\nexport async function dispatchA2AContinuation(\n continuationId: string,\n webhookBaseUrl?: string,\n): Promise<void> {\n const baseUrl =\n webhookBaseUrl ||\n process.env.WEBHOOK_BASE_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n `http://localhost:${process.env.PORT || 3000}`;\n\n const url = `${withConfiguredAppBasePath(baseUrl)}${PROCESSOR_PATH}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n try {\n headers[\"Authorization\"] = `Bearer ${signInternalToken(continuationId)}`;\n } catch (err) {\n if (process.env.NODE_ENV === \"production\") {\n console.error(\n `[integrations] Refusing to dispatch A2A continuation ${continuationId} — A2A_SECRET not configured.`,\n );\n return;\n }\n if (err instanceof Error && !/A2A_SECRET/i.test(err.message)) {\n console.error(\n `[integrations] signInternalToken failed unexpectedly for ${continuationId}:`,\n err,\n );\n }\n }\n\n const dispatchPromise = fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ continuationId }),\n })\n .then(async (response) => {\n if (!response.ok) {\n await logFailedDispatchResponse(continuationId, response);\n }\n })\n .catch((err) => {\n console.error(\n `[integrations] Failed to dispatch A2A continuation ${continuationId}:`,\n err,\n );\n });\n\n await Promise.race([\n dispatchPromise,\n new Promise<void>((resolve) =>\n setTimeout(resolve, DISPATCH_SETTLE_WAIT_MS),\n ),\n ]);\n}\n\nasync function logFailedDispatchResponse(\n continuationId: string,\n response: Response,\n): Promise<void> {\n let body = \"\";\n try {\n body = await response.text();\n } catch {}\n\n const trimmedBody = body.trim();\n console.error(\n `[integrations] A2A continuation ${continuationId} processor dispatch returned HTTP ` +\n `${response.status}${response.statusText ? ` ${response.statusText}` : \"\"}` +\n `${trimmedBody ? `: ${trimmedBody.slice(0, 500)}` : \"\"}`,\n );\n}\n\nexport async function processA2AContinuationById(\n continuationId: string,\n options: { adapters: Map<string, PlatformAdapter> },\n): Promise<void> {\n const shouldClaim = await waitForContinuationDue(continuationId);\n if (!shouldClaim) return;\n const continuation = await claimA2AContinuation(continuationId);\n if (!continuation) return;\n await processClaimedContinuation(continuation, options);\n}\n\nexport async function processDueA2AContinuations(options: {\n adapters: Map<string, PlatformAdapter>;\n limit?: number;\n}): Promise<void> {\n const continuations = await claimDueA2AContinuations(options.limit ?? 5);\n for (const continuation of continuations) {\n await processClaimedContinuation(continuation, options).catch((err) =>\n console.error(\n `[integrations] A2A continuation ${continuation.id} failed:`,\n err,\n ),\n );\n }\n}\n\nasync function processClaimedContinuation(\n continuation: A2AContinuation,\n options: { adapters: Map<string, PlatformAdapter> },\n): Promise<void> {\n const adapter = options.adapters.get(continuation.platform);\n if (!adapter) {\n await failA2AContinuation(\n continuation.id,\n `Unknown platform: ${continuation.platform}`,\n );\n return;\n }\n\n const progress = await resumeA2AContinuationProgress(continuation, adapter);\n\n const auth = await signContinuationToken(continuation);\n const client = new A2AClient(continuation.agentUrl, auth.apiKey, {\n requestTimeoutMs: POLL_REQUEST_TIMEOUT_MS,\n ...(auth.apiKeyFallbacks ? { fallbackApiKeys: auth.apiKeyFallbacks } : {}),\n });\n const deadline = Date.now() + PROCESSOR_WAIT_MS;\n let task: Task | null = null;\n\n try {\n while (Date.now() < deadline) {\n task = await client.getTask(continuation.a2aTaskId);\n if (TERMINAL_STATES.has(task.status.state)) break;\n await reportA2AContinuationProgress(continuation, progress, task);\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n }\n } catch (err) {\n if (isTransientA2APollError(err)) {\n if (shouldStopPollingRemoteTask(continuation)) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n remotePollFailureReason(continuation),\n progress,\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n if (continuation.attempts >= MAX_ATTEMPTS) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n err instanceof Error ? err.message : String(err),\n progress,\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n\n if (!task || !TERMINAL_STATES.has(task.status.state)) {\n if (shouldStopPollingRemoteTask(continuation)) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n remotePollFailureReason(continuation),\n progress,\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(continuation.id);\n return;\n }\n\n if (task.status.state !== \"completed\") {\n const reason =\n extractTaskText(task) ||\n `Remote A2A task ${continuation.a2aTaskId} ended with state ${task.status.state}`;\n await notifyAndFailA2AContinuation(continuation, adapter, reason, progress);\n return;\n }\n\n const text = formatContinuationArtifactText(\n extractTaskText(task),\n continuation.agentUrl,\n );\n if (!text.trim()) {\n await notifyAndFailA2AContinuation(\n continuation,\n adapter,\n `Remote A2A task ${continuation.a2aTaskId} completed without text`,\n progress,\n );\n return;\n }\n\n await deliverAndCompleteA2AContinuation(\n continuation,\n adapter,\n text,\n progress,\n );\n}\n\nasync function resumeA2AContinuationProgress(\n continuation: A2AContinuation,\n adapter: PlatformAdapter,\n): Promise<PlatformRunProgress | null> {\n if (!continuation.progressRef || !adapter.resumeRunProgress) return null;\n try {\n const progress = await adapter.resumeRunProgress(\n continuation.incoming,\n continuation.progressRef,\n );\n if (!progress) return null;\n await progress.onEvent({\n type: \"agent_call_progress\",\n agent: continuation.agentName,\n state: \"working\",\n elapsedSeconds: Math.max(\n 0,\n Math.round((Date.now() - continuation.createdAt) / 1_000),\n ),\n detail: \"Continuing in the background\",\n });\n return progress;\n } catch {\n // A continuation still has a normal reply fallback. Do not log the\n // opaque provider reference or the inbound message payload.\n return null;\n }\n}\n\nasync function reportA2AContinuationProgress(\n continuation: A2AContinuation,\n progress: PlatformRunProgress | null,\n task: Task,\n): Promise<void> {\n if (!progress) return;\n await progress.onEvent({\n type: \"agent_call_progress\",\n agent: continuation.agentName,\n state: task.status.state,\n elapsedSeconds: Math.max(\n 0,\n Math.round((Date.now() - continuation.createdAt) / 1_000),\n ),\n detail: \"Still working on the delegated request\",\n });\n}\n\nasync function waitForContinuationDue(\n continuationId: string,\n): Promise<boolean> {\n const continuation = await getA2AContinuation(continuationId);\n if (!continuation) return false;\n if (continuation.status === \"completed\" || continuation.status === \"failed\") {\n return false;\n }\n if (continuation.status !== \"pending\") return true;\n\n const waitMs = continuation.nextCheckAt - Date.now();\n if (waitMs <= 0) return true;\n\n if (waitMs > MAX_PRE_CLAIM_WAIT_MS) return false;\n\n await sleep(waitMs);\n return true;\n}\n\nasync function notifyAndFailA2AContinuation(\n continuation: A2AContinuation,\n adapter: PlatformAdapter,\n reason: string,\n progress: PlatformRunProgress | null = null,\n): Promise<void> {\n const deliveryContinuation = await claimA2AContinuationDelivery(\n continuation.id,\n );\n if (!deliveryContinuation) return;\n\n const message = formatContinuationFailureMessage(\n deliveryContinuation,\n reason,\n );\n try {\n const outgoing = adapter.formatAgentResponse(message);\n await withTimeout(\n deliverA2AContinuationResponse(\n adapter,\n deliveryContinuation,\n outgoing,\n progress,\n \"error\",\n ),\n PLATFORM_SEND_TIMEOUT_MS,\n `${deliveryContinuation.platform} failure notification timed out`,\n );\n } catch (err) {\n console.error(\n `[integrations] Failed to notify ${deliveryContinuation.platform} about failed A2A continuation ${deliveryContinuation.id}:`,\n err,\n );\n }\n\n await failA2AContinuation(deliveryContinuation.id, reason);\n}\n\nasync function deliverAndCompleteA2AContinuation(\n continuation: A2AContinuation,\n adapter: PlatformAdapter,\n text: string,\n progress: PlatformRunProgress | null = null,\n): Promise<void> {\n const deliveryContinuation = await claimA2AContinuationDelivery(\n continuation.id,\n );\n if (!deliveryContinuation) return;\n\n try {\n const outgoing = adapter.formatAgentResponse(text);\n await withTimeout(\n deliverA2AContinuationResponse(\n adapter,\n deliveryContinuation,\n outgoing,\n progress,\n \"done\",\n ),\n PLATFORM_SEND_TIMEOUT_MS,\n `${deliveryContinuation.platform} response delivery timed out`,\n );\n } catch (err) {\n if (deliveryContinuation.attempts >= MAX_ATTEMPTS) {\n await failA2AContinuation(\n deliveryContinuation.id,\n err instanceof Error ? err.message : String(err),\n );\n return;\n }\n await rescheduleAndRedispatchA2AContinuation(deliveryContinuation.id);\n return;\n }\n\n await completeAfterSuccessfulDelivery(deliveryContinuation);\n}\n\nasync function deliverA2AContinuationResponse(\n adapter: PlatformAdapter,\n continuation: A2AContinuation,\n message: OutgoingMessage,\n progress: PlatformRunProgress | null,\n status: \"done\" | \"error\",\n): Promise<void> {\n if (progress) {\n try {\n await progress.onEvent({\n type: \"agent_call\",\n agent: continuation.agentName,\n status,\n });\n await progress.complete(message);\n return;\n } catch {\n // A resumed Slack stream can no longer be finalized (for example when\n // chat.stopStream rejects). Preserve the final answer with the same\n // thread reply fallback used by the initial webhook run. Also ask the\n // adapter to terminate the native stream: otherwise Slack can keep the\n // task card in its working state after the thread fallback succeeds.\n try {\n await progress.fail?.(\n \"I couldn't update the live response, but I posted the final result in this thread.\",\n );\n } catch {\n // The thread reply below is still the authoritative final answer.\n }\n }\n }\n await adapter.sendResponse(message, continuation.incoming, {\n placeholderRef: continuation.placeholderRef ?? undefined,\n });\n}\n\nasync function rescheduleAndRedispatchA2AContinuation(\n continuationId: string,\n): Promise<void> {\n await rescheduleA2AContinuation(continuationId, RESCHEDULE_DELAY_MS);\n await dispatchA2AContinuation(continuationId).catch((err) => {\n console.error(\n `[integrations] Failed to redispatch A2A continuation ${continuationId}:`,\n err,\n );\n });\n}\n\nasync function completeAfterSuccessfulDelivery(\n continuation: A2AContinuation,\n): Promise<void> {\n let lastError: unknown;\n for (let attempt = 0; attempt < COMPLETE_AFTER_DELIVERY_ATTEMPTS; attempt++) {\n try {\n await completeA2AContinuation(continuation.id);\n return;\n } catch (err) {\n lastError = err;\n }\n }\n\n console.error(\n `[integrations] ${continuation.platform} accepted A2A continuation ${continuation.id}, ` +\n \"but marking it completed failed. Leaving it in delivering for stale-delivery recovery.\",\n lastError,\n );\n}\n\nfunction formatContinuationFailureMessage(\n continuation: A2AContinuation,\n reason: string,\n): string {\n if (isLlmCredentialError(reason)) {\n return formatLlmCredentialErrorMessage({\n agentName: continuation.agentName,\n });\n }\n\n return `The ${continuation.agentName} agent could not finish this request: ${sanitizeFailureReason(\n reason,\n )}`;\n}\n\nfunction isRemoteWorkExpired(continuation: A2AContinuation): boolean {\n return Date.now() - continuation.createdAt >= MAX_REMOTE_WORK_MS;\n}\n\nfunction shouldStopPollingRemoteTask(continuation: A2AContinuation): boolean {\n return (\n continuation.attempts >= MAX_ATTEMPTS || isRemoteWorkExpired(continuation)\n );\n}\n\nfunction isTransientA2APollError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n if (err.name === \"AbortError\") return true;\n return /operation was aborted|aborted|timed out|timeout|Invalid or expired A2A token|A2A request failed \\((?:401|508)\\)/i.test(\n err.message,\n );\n}\n\nfunction remotePollFailureReason(continuation: A2AContinuation): string {\n if (isRemoteWorkExpired(continuation)) {\n return `Timed out polling the ${continuation.agentName} A2A task ${continuation.a2aTaskId} after ${Math.round(\n MAX_REMOTE_WORK_MS / 60_000,\n )} minutes. The downstream agent did not return a final result.`;\n }\n\n return `Timed out polling the ${continuation.agentName} A2A task ${continuation.a2aTaskId} after ${MAX_ATTEMPTS} attempts. The downstream agent did not return a final result.`;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), timeoutMs);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction sanitizeFailureReason(reason: string): string {\n const oneLine = reason.replace(/\\s+/g, \" \").trim();\n const withoutEnvNames = oneLine.replace(\n /\\b[A-Z][A-Z0-9_]*(?:API_KEY|PRIVATE_KEY|SECRET|TOKEN)\\b/g,\n \"a required credential\",\n );\n return (\n withoutEnvNames.slice(0, 500) ||\n \"the downstream agent returned an empty error\"\n );\n}\n\nasync function signContinuationToken(\n continuation: A2AContinuation,\n): Promise<{ apiKey?: string; apiKeyFallbacks?: string[] }> {\n if (continuation.a2aAuthToken === \"\") {\n return {};\n }\n\n const storedToken = continuation.a2aAuthToken;\n if (storedToken && !isLikelyJwt(storedToken)) return { apiKey: storedToken };\n\n const freshTokens = await signFreshContinuationTokens(continuation);\n if (freshTokens.length > 0) {\n return {\n apiKey: freshTokens[0],\n ...(freshTokens.length > 1\n ? { apiKeyFallbacks: freshTokens.slice(1) }\n : {}),\n };\n }\n if (!storedToken) return {};\n\n // Older continuations may have persisted the initial short-lived JWT. Avoid\n // replaying it forever after expiry; opaque legacy bearer keys can still be\n // reused because we cannot re-mint those.\n if (isLikelyJwt(storedToken)) return {};\n return { apiKey: storedToken };\n}\n\nasync function signFreshContinuationTokens(\n continuation: A2AContinuation,\n): Promise<string[]> {\n let orgDomain: string | undefined;\n let orgSecret: string | undefined;\n if (continuation.orgId) {\n try {\n const { getOrgDomain, getOrgA2ASecret } =\n await import(\"../org/context.js\");\n orgDomain = (await getOrgDomain(continuation.orgId)) ?? undefined;\n orgSecret = (await getOrgA2ASecret(continuation.orgId)) ?? undefined;\n } catch {}\n }\n\n if (!continuation.ownerEmail || !(orgSecret || process.env.A2A_SECRET)) {\n return [];\n }\n\n const tokens: string[] = [];\n const add = (token: string | undefined) => {\n if (token && !tokens.includes(token)) tokens.push(token);\n };\n\n if (process.env.A2A_SECRET?.trim()) {\n try {\n add(\n await signA2AToken(continuation.ownerEmail, orgDomain, orgSecret, {\n expiresIn: \"30m\",\n preferGlobalSecret: true,\n }),\n );\n } catch {}\n }\n if (orgSecret) {\n try {\n add(\n await signA2AToken(continuation.ownerEmail, orgDomain, orgSecret, {\n expiresIn: \"30m\",\n preferGlobalSecret: false,\n }),\n );\n } catch {}\n }\n return tokens;\n}\n\nfunction isLikelyJwt(token: string): boolean {\n return token.split(\".\").length === 3;\n}\n\nfunction extractTaskText(task: Task): string {\n const parts = task.status.message?.parts ?? [];\n return parts\n .filter((part): part is { type: \"text\"; text: string } => {\n return part.type === \"text\" && typeof part.text === \"string\";\n })\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\nfunction formatContinuationArtifactText(\n text: string,\n agentUrl: string,\n): string {\n const expandedText = expandRelativeUrls(text, agentUrl);\n return appendA2AArtifactLinks(\n expandedText,\n [{ tool: \"call-agent\", result: expandedText }],\n { baseUrl: resolveArtifactBaseUrl() },\n );\n}\n\nfunction resolveArtifactBaseUrl(): string | undefined {\n const baseUrl =\n process.env.APP_URL || process.env.URL || process.env.DEPLOY_URL;\n return baseUrl ? withConfiguredAppBasePath(baseUrl) : undefined;\n}\n\nfunction expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = publicAgentBaseUrl(agentUrl);\n return text.replace(\n /(^|[\\s([<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n\nfunction publicAgentBaseUrl(agentUrl: string): string {\n try {\n const url = new URL(agentUrl);\n const routeIndex = url.pathname.indexOf(FRAMEWORK_ROUTE_PREFIX);\n url.pathname =\n routeIndex >= 0\n ? url.pathname.slice(0, routeIndex) || \"/\"\n : url.pathname.replace(/\\/+$/, \"\") || \"/\";\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/$/, \"\");\n } catch {\n return agentUrl.replace(/\\/$/, \"\");\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { IncomingMessage } from "./types.js";
1
+ import type { IncomingMessage, PlatformRunProgressRef } from "./types.js";
2
2
  export type A2AContinuationStatus = "pending" | "processing" | "delivering" | "completed" | "failed";
3
3
  export interface A2AContinuation {
4
4
  id: string;
@@ -7,6 +7,8 @@ export interface A2AContinuation {
7
7
  externalThreadId: string;
8
8
  incoming: IncomingMessage;
9
9
  placeholderRef: string | null;
10
+ progressRef: PlatformRunProgressRef | null;
11
+ progressRefClaimed: boolean;
10
12
  ownerEmail: string;
11
13
  orgId: string | null;
12
14
  agentName: string;
@@ -28,6 +30,7 @@ export declare function insertA2AContinuation(input: {
28
30
  externalThreadId: string;
29
31
  incoming: IncomingMessage;
30
32
  placeholderRef?: string | null;
33
+ progressRef?: PlatformRunProgressRef | null;
31
34
  ownerEmail: string;
32
35
  orgId?: string | null;
33
36
  agentName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-continuations-store.d.ts","sourceRoot":"","sources":["../../src/integrations/a2a-continuations-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsHlD,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA4BD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,eAAe,CAAC,CA8C3B;AAED,wBAAsB,oCAAoC,CACxD,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAWjC;AAED,wBAAsB,0CAA0C,CAC9D,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC,CAmB5B;AA8BD,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQjC;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA0CjC;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,SAAI,GACR,OAAO,CAAC,eAAe,EAAE,CAAC,CAmC5B;AAED,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA0BjC;AAED,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvE;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAWf"}
1
+ {"version":3,"file":"a2a-continuations-store.d.ts","sourceRoot":"","sources":["../../src/integrations/a2a-continuations-store.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,8 @@ function buildCreateSql() {
16
16
  external_thread_id TEXT NOT NULL,
17
17
  incoming_payload TEXT NOT NULL,
18
18
  placeholder_ref TEXT,
19
+ progress_ref TEXT,
20
+ progress_ref_claimed ${intType()} NOT NULL DEFAULT 0,
19
21
  owner_email TEXT NOT NULL,
20
22
  org_id TEXT,
21
23
  agent_name TEXT NOT NULL,
@@ -46,7 +48,11 @@ async function ensureTable() {
46
48
  await ensureIndexExists("idx_a2a_continuations_remote_task", `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`);
47
49
  await ensureColumnExists("integration_a2a_continuations", "a2a_auth_token", `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS a2a_auth_token TEXT`);
48
50
  await ensureColumnExists("integration_a2a_continuations", "dedupe_key", `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS dedupe_key TEXT`);
51
+ await ensureColumnExists("integration_a2a_continuations", "progress_ref", `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref TEXT`);
52
+ await ensureColumnExists("integration_a2a_continuations", "progress_ref_claimed", `ALTER TABLE integration_a2a_continuations ADD COLUMN IF NOT EXISTS progress_ref_claimed ${intType()} NOT NULL DEFAULT 0`);
53
+ await backfillProgressRefOwners(client);
49
54
  await ensureIndexExists("idx_a2a_continuations_dedupe_key", `CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`);
55
+ await ensureIndexExists("idx_a2a_continuations_one_progress_owner", `CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`);
50
56
  return;
51
57
  }
52
58
  // SQLite (local dev): keep existing behavior
@@ -56,7 +62,11 @@ async function ensureTable() {
56
62
  await retryOnDdlRace(() => client.execute(`CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_remote_task ON integration_a2a_continuations(integration_task_id, agent_url, a2a_task_id)`));
57
63
  await addColumnIfMissing("a2a_auth_token", "TEXT");
58
64
  await addColumnIfMissing("dedupe_key", "TEXT");
65
+ await addColumnIfMissing("progress_ref", "TEXT");
66
+ await addColumnIfMissing("progress_ref_claimed", `${intType()} NOT NULL DEFAULT 0`);
67
+ await backfillProgressRefOwners(client);
59
68
  await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_a2a_continuations_dedupe_key ON integration_a2a_continuations(integration_task_id, agent_url, dedupe_key)`));
69
+ await retryOnDdlRace(() => client.execute(`CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_continuations_one_progress_owner ON integration_a2a_continuations(integration_task_id) WHERE progress_ref_claimed = 1`));
60
70
  })().catch((err) => {
61
71
  // Retry init on the next call after a failed startup.
62
72
  _initPromise = undefined;
@@ -75,6 +85,63 @@ async function addColumnIfMissing(name, definition) {
75
85
  throw err;
76
86
  }
77
87
  }
88
+ async function backfillProgressRefOwners(client) {
89
+ await client.execute(`
90
+ UPDATE integration_a2a_continuations AS candidate
91
+ SET progress_ref_claimed = 1
92
+ WHERE candidate.progress_ref IS NOT NULL
93
+ AND candidate.status NOT IN ('completed', 'failed')
94
+ AND candidate.progress_ref_claimed = 0
95
+ AND NOT EXISTS (
96
+ SELECT 1
97
+ FROM integration_a2a_continuations AS owner
98
+ WHERE owner.integration_task_id = candidate.integration_task_id
99
+ AND owner.progress_ref_claimed = 1
100
+ )
101
+ AND candidate.id = (
102
+ SELECT selected.id
103
+ FROM integration_a2a_continuations AS selected
104
+ WHERE selected.integration_task_id = candidate.integration_task_id
105
+ AND selected.progress_ref IS NOT NULL
106
+ AND selected.status NOT IN ('completed', 'failed')
107
+ ORDER BY selected.created_at ASC, selected.id ASC
108
+ LIMIT 1
109
+ )
110
+ `);
111
+ }
112
+ const MAX_PROGRESS_REF_KIND_CHARS = 128;
113
+ const MAX_PROGRESS_REF_STREAM_TS_CHARS = 256;
114
+ /**
115
+ * Keep only the tiny, adapter-owned continuation reference. Invalid rows are
116
+ * treated as unavailable rather than throwing during a retry sweep.
117
+ */
118
+ function parseProgressRef(value) {
119
+ if (typeof value !== "string" || value.length === 0)
120
+ return null;
121
+ try {
122
+ const parsed = JSON.parse(value);
123
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
124
+ return null;
125
+ }
126
+ const { kind, streamTs } = parsed;
127
+ if (typeof kind !== "string" ||
128
+ typeof streamTs !== "string" ||
129
+ kind.length === 0 ||
130
+ streamTs.length === 0 ||
131
+ kind.length > MAX_PROGRESS_REF_KIND_CHARS ||
132
+ streamTs.length > MAX_PROGRESS_REF_STREAM_TS_CHARS) {
133
+ return null;
134
+ }
135
+ return { kind, streamTs };
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ }
141
+ function serializeProgressRef(value) {
142
+ const parsed = parseProgressRef(typeof value === "string" ? value : JSON.stringify(value));
143
+ return parsed ? JSON.stringify(parsed) : null;
144
+ }
78
145
  function rowToContinuation(row) {
79
146
  return {
80
147
  id: row.id,
@@ -83,6 +150,8 @@ function rowToContinuation(row) {
83
150
  externalThreadId: row.external_thread_id,
84
151
  incoming: JSON.parse(row.incoming_payload),
85
152
  placeholderRef: row.placeholder_ref ?? null,
153
+ progressRef: parseProgressRef(row.progress_ref),
154
+ progressRefClaimed: Number(row.progress_ref_claimed ?? 0) === 1,
86
155
  ownerEmail: row.owner_email,
87
156
  orgId: row.org_id ?? null,
88
157
  agentName: row.agent_name,
@@ -105,13 +174,14 @@ export async function insertA2AContinuation(input) {
105
174
  const now = Date.now();
106
175
  const id = `a2a-cont-${now}-${Math.random().toString(36).slice(2, 8)}`;
107
176
  const payload = JSON.stringify(input.incoming);
177
+ const progressRef = serializeProgressRef(input.progressRef);
108
178
  try {
109
179
  await client.execute({
110
180
  sql: `INSERT INTO integration_a2a_continuations
111
181
  (id, integration_task_id, platform, external_thread_id, incoming_payload,
112
- placeholder_ref, owner_email, org_id, agent_name, agent_url, dedupe_key, a2a_task_id, a2a_auth_token,
182
+ placeholder_ref, progress_ref, progress_ref_claimed, owner_email, org_id, agent_name, agent_url, dedupe_key, a2a_task_id, a2a_auth_token,
113
183
  status, attempts, next_check_at, created_at, updated_at)
114
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
184
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
115
185
  args: [
116
186
  id,
117
187
  input.integrationTaskId,
@@ -119,6 +189,8 @@ export async function insertA2AContinuation(input) {
119
189
  input.externalThreadId,
120
190
  payload,
121
191
  input.placeholderRef ?? null,
192
+ null,
193
+ 0,
122
194
  input.ownerEmail,
123
195
  input.orgId ?? null,
124
196
  input.agentName,
@@ -133,14 +205,66 @@ export async function insertA2AContinuation(input) {
133
205
  now,
134
206
  ],
135
207
  });
136
- return (await getA2AContinuation(id));
137
208
  }
138
209
  catch (err) {
139
210
  if (!isDuplicateContinuationError(err))
140
211
  throw err;
141
212
  const existing = await findA2AContinuation(input.integrationTaskId, input.agentUrl, input.a2aTaskId);
142
- if (existing)
213
+ if (existing) {
214
+ // A retry can reach this row after the original invocation created it
215
+ // without a resumable progress surface (or with one that has gone
216
+ // stale). Keep the most recent valid adapter reference for active work,
217
+ // but never resurrect short-lived delivery state after a terminal row
218
+ // has deliberately scrubbed it.
219
+ if (progressRef &&
220
+ existing.status !== "completed" &&
221
+ existing.status !== "failed") {
222
+ if (existing.progressRefClaimed) {
223
+ if (JSON.stringify(existing.progressRef) !== progressRef) {
224
+ await client.execute({
225
+ sql: `UPDATE integration_a2a_continuations
226
+ SET progress_ref = ?, updated_at = ?
227
+ WHERE id = ? AND status NOT IN ('completed', 'failed')
228
+ AND progress_ref_claimed = 1
229
+ AND (progress_ref IS NULL OR progress_ref <> ?)`,
230
+ args: [progressRef, now, existing.id, progressRef],
231
+ });
232
+ }
233
+ }
234
+ else {
235
+ await claimA2AContinuationProgressRef(existing.id, progressRef);
236
+ }
237
+ return (await getA2AContinuation(existing.id)) ?? existing;
238
+ }
143
239
  return existing;
240
+ }
241
+ throw err;
242
+ }
243
+ if (progressRef) {
244
+ await claimA2AContinuationProgressRef(id, progressRef);
245
+ }
246
+ return (await getA2AContinuation(id));
247
+ }
248
+ /**
249
+ * A native platform stream has one terminal completion. Claim it for a single
250
+ * downstream continuation, and retain the ownership marker after terminal
251
+ * cleanup scrubs the short-lived stream reference. The partial unique index
252
+ * makes concurrent downstream inserts safe across processes.
253
+ */
254
+ async function claimA2AContinuationProgressRef(id, progressRef) {
255
+ try {
256
+ await getDbExec().execute({
257
+ sql: `UPDATE integration_a2a_continuations
258
+ SET progress_ref = ?, progress_ref_claimed = 1
259
+ WHERE id = ? AND progress_ref_claimed = 0`,
260
+ args: [progressRef, id],
261
+ });
262
+ }
263
+ catch (err) {
264
+ // A sibling continuation already owns this stream and will finalize it.
265
+ // This continuation still delivers through the normal response path.
266
+ if (isDuplicateContinuationError(err))
267
+ return;
144
268
  throw err;
145
269
  }
146
270
  }
@@ -334,7 +458,7 @@ export async function completeA2AContinuation(id) {
334
458
  await client.execute({
335
459
  sql: `UPDATE integration_a2a_continuations
336
460
  SET status = ?, updated_at = ?, completed_at = ?,
337
- incoming_payload = ?, a2a_auth_token = NULL
461
+ incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL
338
462
  WHERE id = ? AND status IN ('processing', 'delivering', 'completed')`,
339
463
  args: ["completed", now, now, "{}", id],
340
464
  });
@@ -346,7 +470,7 @@ export async function failA2AContinuation(id, errorMessage) {
346
470
  await client.execute({
347
471
  sql: `UPDATE integration_a2a_continuations
348
472
  SET status = ?, updated_at = ?, error_message = ?,
349
- incoming_payload = ?, a2a_auth_token = NULL
473
+ incoming_payload = ?, a2a_auth_token = NULL, progress_ref = NULL
350
474
  WHERE id = ? AND status <> 'completed'`,
351
475
  args: ["failed", now, errorMessage.slice(0, 2000), "{}", id],
352
476
  });