@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.
- package/corpus/core/CHANGELOG.md +8 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/artifact-response.ts +154 -1
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +118 -31
- package/corpus/core/src/integrations/a2a-continuations-store.ts +165 -7
- package/corpus/core/src/integrations/adapters/slack.ts +77 -7
- package/corpus/core/src/integrations/types.ts +30 -0
- package/corpus/core/src/integrations/webhook-handler.ts +54 -18
- package/corpus/core/src/scripts/call-agent.ts +1 -0
- package/corpus/core/src/server/request-context.ts +2 -0
- package/dist/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +127 -1
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +76 -21
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts +4 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +130 -6
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +56 -7
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/types.d.ts +25 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.js +54 -16
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +1 -0
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/request-context.d.ts +2 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- 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
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
});
|