@adcp/sdk 13.0.4 → 13.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adcp-grade.js +4 -3
- package/bin/adcp.js +18 -0
- package/dist/lib/conformance/invariants/uniformError.d.ts.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.js +21 -0
- package/dist/lib/conformance/invariants/uniformError.js.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +22 -1
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/core/AgentClient.d.mts +1 -1
- package/dist/lib/core/AgentClient.d.ts +1 -1
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/AgentClient.js +1 -1
- package/dist/lib/core/AgentClient.js.map +1 -1
- package/dist/lib/core/AgentClient.mjs +1 -1
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +88 -48
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +88 -48
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
- package/dist/lib/core/TaskExecutor.js +8 -4
- package/dist/lib/core/TaskExecutor.js.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +8 -4
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/net/agent-transport-fetch.d.mts +15 -0
- package/dist/lib/net/agent-transport-fetch.d.ts +15 -0
- package/dist/lib/net/agent-transport-fetch.d.ts.map +1 -1
- package/dist/lib/net/agent-transport-fetch.js +37 -2
- package/dist/lib/net/agent-transport-fetch.js.map +1 -1
- package/dist/lib/net/agent-transport-fetch.mjs +37 -2
- package/dist/lib/net/agent-transport-fetch.mjs.map +1 -1
- package/dist/lib/net/credential-headers.d.mts +1 -0
- package/dist/lib/net/credential-headers.d.ts +2 -0
- package/dist/lib/net/credential-headers.d.ts.map +1 -0
- package/dist/lib/net/credential-headers.js +34 -0
- package/dist/lib/net/credential-headers.js.map +1 -0
- package/dist/lib/net/credential-headers.mjs +10 -0
- package/dist/lib/net/credential-headers.mjs.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.d.mts +18 -0
- package/dist/lib/protocols/a2a-native-v1.d.ts +19 -0
- package/dist/lib/protocols/a2a-native-v1.d.ts.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.js +183 -0
- package/dist/lib/protocols/a2a-native-v1.js.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.mjs +167 -0
- package/dist/lib/protocols/a2a-native-v1.mjs.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.d.mts +13 -0
- package/dist/lib/protocols/a2a-push-notification.d.ts +14 -0
- package/dist/lib/protocols/a2a-push-notification.d.ts.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.js +42 -0
- package/dist/lib/protocols/a2a-push-notification.js.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.mjs +23 -0
- package/dist/lib/protocols/a2a-push-notification.mjs.map +1 -0
- package/dist/lib/protocols/a2a.d.mts +15 -5
- package/dist/lib/protocols/a2a.d.ts +15 -5
- package/dist/lib/protocols/a2a.d.ts.map +1 -1
- package/dist/lib/protocols/a2a.js +102 -13
- package/dist/lib/protocols/a2a.js.map +1 -1
- package/dist/lib/protocols/a2a.mjs +90 -12
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/index.d.mts +3 -0
- package/dist/lib/protocols/index.d.ts +3 -0
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +18 -6
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/index.mjs +18 -6
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-modern.js +3 -1
- package/dist/lib/protocols/mcp-modern.js.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +3 -1
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp-tasks.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-tasks.js +2 -1
- package/dist/lib/protocols/mcp-tasks.js.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +2 -1
- package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
- package/dist/lib/protocols/mcp.d.mts +8 -5
- package/dist/lib/protocols/mcp.d.ts +8 -5
- package/dist/lib/protocols/mcp.d.ts.map +1 -1
- package/dist/lib/protocols/mcp.js +12 -4
- package/dist/lib/protocols/mcp.js.map +1 -1
- package/dist/lib/protocols/mcp.mjs +12 -4
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.d.mts +9 -1
- package/dist/lib/protocols/rawResponseCapture.d.ts +9 -1
- package/dist/lib/protocols/rawResponseCapture.d.ts.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.js +153 -10
- package/dist/lib/protocols/rawResponseCapture.js.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.mjs +153 -10
- package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/signing/agent-fetch.d.mts +3 -1
- package/dist/lib/signing/agent-fetch.d.ts +3 -1
- package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
- package/dist/lib/signing/agent-fetch.js +4 -2
- package/dist/lib/signing/agent-fetch.js.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +4 -2
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/protocol-methods.d.mts +24 -0
- package/dist/lib/signing/protocol-methods.d.ts +25 -0
- package/dist/lib/signing/protocol-methods.d.ts.map +1 -0
- package/dist/lib/signing/protocol-methods.js +51 -0
- package/dist/lib/signing/protocol-methods.js.map +1 -0
- package/dist/lib/signing/protocol-methods.mjs +25 -0
- package/dist/lib/signing/protocol-methods.mjs.map +1 -0
- package/dist/lib/signing/types.d.mts +2 -0
- package/dist/lib/signing/types.d.ts +2 -0
- package/dist/lib/signing/types.d.ts.map +1 -1
- package/dist/lib/signing/types.js.map +1 -1
- package/dist/lib/signing/types.mjs.map +1 -1
- package/dist/lib/signing/verifier.d.ts.map +1 -1
- package/dist/lib/signing/verifier.js +6 -2
- package/dist/lib/signing/verifier.js.map +1 -1
- package/dist/lib/signing/verifier.mjs +6 -2
- package/dist/lib/signing/verifier.mjs.map +1 -1
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +4 -1
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +4 -1
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +3 -0
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +3 -0
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.d.mts +3 -1
- package/dist/lib/testing/storyboard/agent-routing.d.ts +3 -1
- package/dist/lib/testing/storyboard/agent-routing.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.js +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.mjs +4 -2
- package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
- package/dist/lib/testing/storyboard/compliance.d.mts +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/compliance.js +4 -1
- package/dist/lib/testing/storyboard/compliance.js.map +1 -1
- package/dist/lib/testing/storyboard/compliance.mjs +4 -1
- package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.mts +7 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.ts +8 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.js +45 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.js.map +1 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.mjs +21 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.mjs.map +1 -0
- package/dist/lib/testing/storyboard/probes.d.mts +2 -0
- package/dist/lib/testing/storyboard/probes.d.ts +2 -0
- package/dist/lib/testing/storyboard/probes.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/probes.js +3 -2
- package/dist/lib/testing/storyboard/probes.js.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +3 -2
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.mts +31 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts +32 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js +279 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs +244 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/builder.d.mts +4 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts +4 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +19 -0
- package/dist/lib/testing/storyboard/request-signing/builder.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +19 -0
- package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.d.mts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.js +82 -13
- package/dist/lib/testing/storyboard/request-signing/grader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +86 -13
- package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.d.mts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.d.ts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.js +7 -0
- package/dist/lib/testing/storyboard/request-signing/index.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.mjs +8 -0
- package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +2 -2
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +2 -2
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +6 -5
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +6 -5
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.d.mts +1 -0
- package/dist/lib/testing/storyboard/request-signing/types.d.ts +1 -0
- package/dist/lib/testing/storyboard/request-signing/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +1 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +1 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.mts +28 -1
- package/dist/lib/testing/storyboard/runner.d.ts +28 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +251 -55
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +255 -60
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.d.mts +4 -2
- package/dist/lib/testing/storyboard/types.d.ts +4 -2
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js +1 -0
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs +1 -0
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +97 -22
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +98 -22
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +1 -1
- package/docs/llms.txt +5 -3
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["// Official A2A client implementation - NO FALLBACKS\nimport { A2AClient as A2AClientImpl } from '@a2a-js/sdk/client';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { createHmac } from 'node:crypto';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\n// The A2A SDK client is used untyped: request/response shapes are validated at\n// runtime against the AdCP wire contract, not against the SDK's exported\n// types. Preserves the prior behaviour of the CommonJS `require` form.\nconst A2AClient: any = A2AClientImpl;\n\nif (!A2AClient) {\n throw new Error('A2A SDK client is required. Please install @a2a-js/sdk');\n}\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n}\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, InstanceType<typeof A2AClient>>();\nconst pendingA2AClients = new Map<string, Promise<InstanceType<typeof A2AClient>>>();\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>\n): string {\n // 64-bit Map-key disambiguator — NOT a password hash. The cached client\n // closes over the full credential, so a hypothetical hash collision still\n // sends the original credential on the wire, just possibly cache-miss\n // and reconnect. Routed via `cacheDisambiguator` (HMAC-SHA256 with empty\n // key) instead of bare `createHash` so CodeQL's\n // `js/insufficient-password-hash` heuristic doesn't misclassify the\n // dataflow — see the helper docstring for the full rationale.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const tokenSuffix = fingerprint ? `::${cacheDisambiguator(fingerprint)}` : '';\n const headersKey = headersCacheDisambiguator(customHeaders);\n const headersSuffix = headersKey ? `::headers:${headersKey}` : '';\n const signingSuffix = signingCacheKey ? `::${signingCacheKey}` : '';\n return `${agentUrl}${tokenSuffix}${headersSuffix}${signingSuffix}`;\n}\n\n/**\n * Produce a stable 64-bit Map-key disambiguator from credential material.\n * Mirrors the helper in `src/lib/protocols/mcp.ts` — the two protocol\n * modules intentionally don't share runtime imports, so each carries its\n * own copy. See the MCP-side docstring for the full rationale.\n */\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex').slice(0, 16);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheDisambiguator(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? cacheDisambiguator(JSON.stringify(entries)) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A tasks/cancel for an in-flight task (A2A 0.3.0 §7.4).\n *\n * Sends a raw JSON-RPC 2.0 POST directly to the agent endpoint with the same\n * auth header shape as `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT\n * enter `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // POST is JSON-RPC at the bare A2A endpoint. Calling this on an MCP agent\n // would POST `tasks/cancel` JSON-RPC at an MCP endpoint and 404. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const transportFetch = createAgentTransportFetch(agentUrl, { trustedFetchFn: fetchFn, allowPrivateIp });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n if (authToken) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n await client.cancelTask({ id: taskId });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<InstanceType<typeof A2AClient>> {\n const signingContext = signingContextStorage.getStore();\n const fetchFn = callContextStorage.getStore()?.fetchFn;\n const cacheKey = a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, customHeaders);\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = a2aClientCache.get(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n a2aClientCache.set(cacheKey, client);\n return client;\n })\n .finally(() => {\n pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(\n agentUrl: string,\n authToken: string | undefined\n): Promise<InstanceType<typeof A2AClient>> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: callContextStorage.getStore()?.fetchFn,\n allowPrivateIp: callContextStorage.getStore()?.allowPrivateIp,\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const urlString = typeof url === 'string' ? url : url.toString();\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...context?.customHeaders,\n ...(authToken && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states per A2A 0.3.0 §3.4. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient; see AgentClient.getContextId() / getPendingTaskId().\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n\n const requestPayload: {\n message: {\n messageId: string;\n role: string;\n kind: string;\n parts: Array<{ kind: string; data: { skill: string; parameters: Record<string, unknown> } }>;\n contextId?: string;\n taskId?: string;\n };\n configuration?: { pushNotificationConfig: PushNotificationConfig };\n } = {\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: 'user',\n kind: 'message',\n parts: [\n {\n kind: 'data',\n data: {\n skill: toolName,\n parameters: parameters,\n },\n },\n ],\n ...(session?.contextId && { contextId: session.contextId }),\n ...(session?.taskId && { taskId: session.taskId }),\n },\n };\n\n if (pushNotificationConfig) {\n requestPayload.configuration = {\n pushNotificationConfig: pushNotificationConfig,\n };\n }\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n kind: 'data',\n data: { skill: toolName, parameters: redactedParameters },\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n pushNotificationConfig: redactPushNotificationConfigForDebug(\n requestPayload.configuration.pushNotificationConfig\n )!,\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const messageResponse = await client.sendMessage(requestPayload);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, context.customHeaders));\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["import_client","A2AClientImpl"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["// Official A2A client implementation - NO FALLBACKS\nimport { A2AClient as A2AClientImpl } from '@a2a-js/sdk/client';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { createHmac } from 'node:crypto';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\n// The A2A SDK client is used untyped: request/response shapes are validated at\n// runtime against the AdCP wire contract, not against the SDK's exported\n// types. Preserves the prior behaviour of the CommonJS `require` form.\nconst A2AClient: any = A2AClientImpl;\n\nif (!A2AClient) {\n throw new Error('A2A SDK client is required. Please install @a2a-js/sdk');\n}\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n legacyCompat?: A2ALegacyCompatOptions;\n}\n\n/** Controls whether A2A v0.3 compatibility is accepted. */\nexport interface A2ALegacyCompatOptions {\n enabled: boolean;\n}\n\nconst DEFAULT_A2A_LEGACY_COMPAT: Readonly<A2ALegacyCompatOptions> = Object.freeze({ enabled: true });\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, InstanceType<typeof A2AClient>>();\nconst pendingA2AClients = new Map<string, Promise<InstanceType<typeof A2AClient>>>();\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>\n): string {\n // 64-bit Map-key disambiguator — NOT a password hash. The cached client\n // closes over the full credential, so a hypothetical hash collision still\n // sends the original credential on the wire, just possibly cache-miss\n // and reconnect. Routed via `cacheDisambiguator` (HMAC-SHA256 with empty\n // key) instead of bare `createHash` so CodeQL's\n // `js/insufficient-password-hash` heuristic doesn't misclassify the\n // dataflow — see the helper docstring for the full rationale.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const tokenSuffix = fingerprint ? `::${cacheDisambiguator(fingerprint)}` : '';\n const headersKey = headersCacheDisambiguator(customHeaders);\n const headersSuffix = headersKey ? `::headers:${headersKey}` : '';\n const signingSuffix = signingCacheKey ? `::${signingCacheKey}` : '';\n return `${agentUrl}${tokenSuffix}${headersSuffix}${signingSuffix}`;\n}\n\n/**\n * Produce a stable 64-bit Map-key disambiguator from credential material.\n * Mirrors the helper in `src/lib/protocols/mcp.ts` — the two protocol\n * modules intentionally don't share runtime imports, so each carries its\n * own copy. See the MCP-side docstring for the full rationale.\n */\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex').slice(0, 16);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheDisambiguator(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? cacheDisambiguator(JSON.stringify(entries)) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A tasks/cancel for an in-flight task (A2A 0.3.0 §7.4).\n *\n * Uses the official A2A SDK cancel method with the same auth header shape as\n * `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT enter\n * `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean,\n legacyCompat: A2ALegacyCompatOptions = DEFAULT_A2A_LEGACY_COMPAT\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // POST is JSON-RPC at the bare A2A endpoint. Calling this on an MCP agent\n // would POST `tasks/cancel` JSON-RPC at an MCP endpoint and 404. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const configuredHeaders = agent.headers ?? {};\n const transportFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: fetchFn,\n allowPrivateIp,\n originBoundHeaders: Object.keys(configuredHeaders),\n crossOriginCredentialPolicy: legacyCompat.enabled === false ? 'refuse' : 'strip',\n });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n const requestUrl = new URL(input instanceof Request ? input.url : input.toString());\n const nativeCrossOrigin = legacyCompat.enabled === false && requestUrl.origin !== new URL(agentUrl).origin;\n if (nativeCrossOrigin && (authToken || agent.request_signing)) {\n const credentialHeaderNames = [\n ...(authToken ? ['authorization', 'x-adcp-auth'] : []),\n ...(agent.request_signing ? ['content-digest', 'signature', 'signature-input'] : []),\n ];\n throw new Error(\n `A2A native cancel refused credentialed cross-origin dispatch to ${requestUrl.origin}; ` +\n `credential headers: ${credentialHeaderNames.join(', ')}`\n );\n }\n if (authToken && !nativeCrossOrigin) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n if (!nativeCrossOrigin) {\n for (const [name, value] of Object.entries(configuredHeaders)) headers.set(name, value);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await createA2AClientFromCardUrl(cardUrl, fetchImpl, legacyCompat);\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n if (legacyCompat.enabled === false) {\n const { createNativeCancelTaskRequest } = await import('./a2a-native-v1');\n await client.cancelTask(createNativeCancelTaskRequest(taskId));\n } else {\n await client.cancelTask({ id: taskId });\n }\n}\n\n/**\n * Build an official A2A client from a card URL. Ordinary calls retain the\n * stable SDK's v0.3 client; native-only compliance calls use the separately\n * pinned official 1.0 client.\n */\nexport async function createA2AClientFromCardUrl(\n cardUrl: string,\n fetchImpl: typeof fetch,\n legacyCompat: A2ALegacyCompatOptions = DEFAULT_A2A_LEGACY_COMPAT\n): Promise<any> {\n if (legacyCompat.enabled === false) {\n const { createNativeA2AClientFromCardUrl } = await import('./a2a-native-v1');\n return createNativeA2AClientFromCardUrl(cardUrl, fetchImpl);\n }\n return A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<InstanceType<typeof A2AClient>> {\n const signingContext = signingContextStorage.getStore();\n const fetchFn = callContextStorage.getStore()?.fetchFn;\n const cacheKey = a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, customHeaders);\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = a2aClientCache.get(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n a2aClientCache.set(cacheKey, client);\n return client;\n })\n .finally(() => {\n pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(\n agentUrl: string,\n authToken: string | undefined\n): Promise<InstanceType<typeof A2AClient>> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const creationContext = callContextStorage.getStore();\n const originBoundCustomHeaderNames = Object.keys(creationContext?.customHeaders ?? {});\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: creationContext?.fetchFn,\n allowPrivateIp: creationContext?.allowPrivateIp,\n originBoundHeaders: originBoundCustomHeaderNames,\n crossOriginCredentialPolicy: creationContext?.legacyCompat?.enabled === false ? 'refuse' : 'strip',\n onOriginBoundHeadersStripped: (headerNames, target) => {\n callContextStorage.getStore()?.debugLogs.push({\n type: 'warning',\n message: `A2A: Stripped configured origin-bound headers (${headerNames.join(', ')}) before cross-origin dispatch to ${target.origin}`,\n timestamp: new Date().toISOString(),\n });\n },\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const urlString = typeof url === 'string' ? url : url.toString();\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const nativeCrossOrigin =\n context?.legacyCompat?.enabled === false && new URL(urlString).origin !== new URL(agentUrl).origin;\n if (nativeCrossOrigin && (authToken || signingContext)) {\n const targetOrigin = new URL(urlString).origin;\n const credentialHeaderNames = [\n ...(authToken ? ['authorization', 'x-adcp-auth'] : []),\n ...(signingContext ? ['content-digest', 'signature', 'signature-input'] : []),\n ];\n throw new Error(\n `A2A native dispatch refused credentialed cross-origin endpoint ${targetOrigin}; ` +\n `credential headers: ${credentialHeaderNames.join(', ')}`\n );\n }\n const customHeaders = nativeCrossOrigin ? undefined : context?.customHeaders;\n if (nativeCrossOrigin && Object.keys(context?.customHeaders ?? {}).length > 0) {\n context?.debugLogs.push({\n type: 'warning',\n message: `A2A: Stripped configured origin-bound headers before cross-origin dispatch to ${new URL(urlString).origin}`,\n timestamp: new Date().toISOString(),\n });\n }\n const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...customHeaders,\n ...(authToken &&\n !nativeCrossOrigin && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states per A2A 0.3.0 §3.4. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient; see AgentClient.getContextId() / getPendingTaskId().\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean,\n legacyCompat?: A2ALegacyCompatOptions\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n legacyCompat,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n if (context.legacyCompat?.enabled === false) {\n const { callNativeA2ATool } = await import('./a2a-native-v1');\n return await callNativeA2ATool({\n cardUrls: buildCardUrls(agentUrl),\n fetchImpl: buildFetchImpl(authToken, agentUrl),\n toolName,\n parameters,\n pushNotificationConfig,\n contextId: session?.contextId,\n taskId: session?.taskId,\n signal: context.signal,\n });\n }\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n\n const requestPayload: {\n message: {\n messageId: string;\n role: string;\n kind: string;\n parts: Array<{ kind: string; data: { skill: string; parameters: Record<string, unknown> } }>;\n contextId?: string;\n taskId?: string;\n };\n configuration?: { pushNotificationConfig: PushNotificationConfig };\n } = {\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: 'user',\n kind: 'message',\n parts: [\n {\n kind: 'data',\n data: {\n skill: toolName,\n parameters: parameters,\n },\n },\n ],\n ...(session?.contextId && { contextId: session.contextId }),\n ...(session?.taskId && { taskId: session.taskId }),\n },\n };\n\n if (pushNotificationConfig) {\n requestPayload.configuration = {\n pushNotificationConfig: pushNotificationConfig,\n };\n }\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n kind: 'data',\n data: { skill: toolName, parameters: redactedParameters },\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n pushNotificationConfig: redactPushNotificationConfigForDebug(\n requestPayload.configuration.pushNotificationConfig\n )!,\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const messageResponse = await client.sendMessage(requestPayload);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, context.customHeaders));\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["import_client","A2AClientImpl"]}
|
|
@@ -27,6 +27,7 @@ const A2AClient = A2AClientImpl;
|
|
|
27
27
|
if (!A2AClient) {
|
|
28
28
|
throw new Error("A2A SDK client is required. Please install @a2a-js/sdk");
|
|
29
29
|
}
|
|
30
|
+
const DEFAULT_A2A_LEGACY_COMPAT = Object.freeze({ enabled: true });
|
|
30
31
|
const callContextStorage = new AsyncLocalStorage();
|
|
31
32
|
const a2aClientCache = /* @__PURE__ */ new Map();
|
|
32
33
|
const pendingA2AClients = /* @__PURE__ */ new Map();
|
|
@@ -76,12 +77,18 @@ function closeA2AConnections() {
|
|
|
76
77
|
pendingA2AClients.clear();
|
|
77
78
|
}
|
|
78
79
|
const CANCEL_TIMEOUT_MS = 5e3;
|
|
79
|
-
async function cancelA2ATask(agent, taskId, fetchFn, allowPrivateIp) {
|
|
80
|
+
async function cancelA2ATask(agent, taskId, fetchFn, allowPrivateIp, legacyCompat = DEFAULT_A2A_LEGACY_COMPAT) {
|
|
80
81
|
if (agent.protocol !== "a2a") {
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
const agentUrl = agent.agent_uri;
|
|
84
|
-
const
|
|
85
|
+
const configuredHeaders = agent.headers ?? {};
|
|
86
|
+
const transportFetch = createAgentTransportFetch(agentUrl, {
|
|
87
|
+
trustedFetchFn: fetchFn,
|
|
88
|
+
allowPrivateIp,
|
|
89
|
+
originBoundHeaders: Object.keys(configuredHeaders),
|
|
90
|
+
crossOriginCredentialPolicy: legacyCompat.enabled === false ? "refuse" : "strip"
|
|
91
|
+
});
|
|
85
92
|
const authToken = agent.auth_token;
|
|
86
93
|
let requestFetch = (input, init) => transportFetch(input, init);
|
|
87
94
|
if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {
|
|
@@ -92,10 +99,24 @@ async function cancelA2ATask(agent, taskId, fetchFn, allowPrivateIp) {
|
|
|
92
99
|
const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);
|
|
93
100
|
const fetchImpl = (input, init = {}) => {
|
|
94
101
|
const headers = new Headers(init.headers);
|
|
95
|
-
|
|
102
|
+
const requestUrl = new URL(input instanceof Request ? input.url : input.toString());
|
|
103
|
+
const nativeCrossOrigin = legacyCompat.enabled === false && requestUrl.origin !== new URL(agentUrl).origin;
|
|
104
|
+
if (nativeCrossOrigin && (authToken || agent.request_signing)) {
|
|
105
|
+
const credentialHeaderNames = [
|
|
106
|
+
...authToken ? ["authorization", "x-adcp-auth"] : [],
|
|
107
|
+
...agent.request_signing ? ["content-digest", "signature", "signature-input"] : []
|
|
108
|
+
];
|
|
109
|
+
throw new Error(
|
|
110
|
+
`A2A native cancel refused credentialed cross-origin dispatch to ${requestUrl.origin}; credential headers: ${credentialHeaderNames.join(", ")}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
if (authToken && !nativeCrossOrigin) {
|
|
96
114
|
headers.set("authorization", `Bearer ${authToken}`);
|
|
97
115
|
headers.set("x-adcp-auth", authToken);
|
|
98
116
|
}
|
|
117
|
+
if (!nativeCrossOrigin) {
|
|
118
|
+
for (const [name, value] of Object.entries(configuredHeaders)) headers.set(name, value);
|
|
119
|
+
}
|
|
99
120
|
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
100
121
|
return requestFetch(input, { ...init, headers, signal });
|
|
101
122
|
};
|
|
@@ -103,14 +124,26 @@ async function cancelA2ATask(agent, taskId, fetchFn, allowPrivateIp) {
|
|
|
103
124
|
let lastError;
|
|
104
125
|
for (const cardUrl of buildCardUrls(agentUrl)) {
|
|
105
126
|
try {
|
|
106
|
-
client = await
|
|
127
|
+
client = await createA2AClientFromCardUrl(cardUrl, fetchImpl, legacyCompat);
|
|
107
128
|
break;
|
|
108
129
|
} catch (err) {
|
|
109
130
|
lastError = err;
|
|
110
131
|
}
|
|
111
132
|
}
|
|
112
133
|
if (!client) throw lastError instanceof Error ? lastError : new Error("A2A agent card discovery failed");
|
|
113
|
-
|
|
134
|
+
if (legacyCompat.enabled === false) {
|
|
135
|
+
const { createNativeCancelTaskRequest } = await import("./a2a-native-v1.mjs");
|
|
136
|
+
await client.cancelTask(createNativeCancelTaskRequest(taskId));
|
|
137
|
+
} else {
|
|
138
|
+
await client.cancelTask({ id: taskId });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function createA2AClientFromCardUrl(cardUrl, fetchImpl, legacyCompat = DEFAULT_A2A_LEGACY_COMPAT) {
|
|
142
|
+
if (legacyCompat.enabled === false) {
|
|
143
|
+
const { createNativeA2AClientFromCardUrl } = await import("./a2a-native-v1.mjs");
|
|
144
|
+
return createNativeA2AClientFromCardUrl(cardUrl, fetchImpl);
|
|
145
|
+
}
|
|
146
|
+
return A2AClient.fromCardUrl(cardUrl, { fetchImpl });
|
|
114
147
|
}
|
|
115
148
|
async function getOrCreateA2AClient(agentUrl, authToken, customHeaders, bypassCache = false) {
|
|
116
149
|
const signingContext = signingContextStorage.getStore();
|
|
@@ -157,9 +190,20 @@ async function createA2AClient(agentUrl, authToken) {
|
|
|
157
190
|
}
|
|
158
191
|
function buildFetchImpl(authToken, agentUrl) {
|
|
159
192
|
const signingContext = signingContextStorage.getStore();
|
|
193
|
+
const creationContext = callContextStorage.getStore();
|
|
194
|
+
const originBoundCustomHeaderNames = Object.keys(creationContext?.customHeaders ?? {});
|
|
160
195
|
const pinnedFetch = createAgentTransportFetch(agentUrl, {
|
|
161
|
-
trustedFetchFn:
|
|
162
|
-
allowPrivateIp:
|
|
196
|
+
trustedFetchFn: creationContext?.fetchFn,
|
|
197
|
+
allowPrivateIp: creationContext?.allowPrivateIp,
|
|
198
|
+
originBoundHeaders: originBoundCustomHeaderNames,
|
|
199
|
+
crossOriginCredentialPolicy: creationContext?.legacyCompat?.enabled === false ? "refuse" : "strip",
|
|
200
|
+
onOriginBoundHeadersStripped: (headerNames, target) => {
|
|
201
|
+
callContextStorage.getStore()?.debugLogs.push({
|
|
202
|
+
type: "warning",
|
|
203
|
+
message: `A2A: Stripped configured origin-bound headers (${headerNames.join(", ")}) before cross-origin dispatch to ${target.origin}`,
|
|
204
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
205
|
+
});
|
|
206
|
+
}
|
|
163
207
|
});
|
|
164
208
|
const networkFetch = wrapFetchWithTransportDiagnostics(
|
|
165
209
|
wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))
|
|
@@ -182,13 +226,32 @@ function buildFetchImpl(authToken, agentUrl) {
|
|
|
182
226
|
}
|
|
183
227
|
const urlString = typeof url === "string" ? url : url.toString();
|
|
184
228
|
const isDiscoveryRequest = isAgentCardPath(urlString);
|
|
229
|
+
const nativeCrossOrigin = context?.legacyCompat?.enabled === false && new URL(urlString).origin !== new URL(agentUrl).origin;
|
|
230
|
+
if (nativeCrossOrigin && (authToken || signingContext)) {
|
|
231
|
+
const targetOrigin = new URL(urlString).origin;
|
|
232
|
+
const credentialHeaderNames = [
|
|
233
|
+
...authToken ? ["authorization", "x-adcp-auth"] : [],
|
|
234
|
+
...signingContext ? ["content-digest", "signature", "signature-input"] : []
|
|
235
|
+
];
|
|
236
|
+
throw new Error(
|
|
237
|
+
`A2A native dispatch refused credentialed cross-origin endpoint ${targetOrigin}; credential headers: ${credentialHeaderNames.join(", ")}`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const customHeaders = nativeCrossOrigin ? void 0 : context?.customHeaders;
|
|
241
|
+
if (nativeCrossOrigin && Object.keys(context?.customHeaders ?? {}).length > 0) {
|
|
242
|
+
context?.debugLogs.push({
|
|
243
|
+
type: "warning",
|
|
244
|
+
message: `A2A: Stripped configured origin-bound headers before cross-origin dispatch to ${new URL(urlString).origin}`,
|
|
245
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
246
|
+
});
|
|
247
|
+
}
|
|
185
248
|
const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();
|
|
186
249
|
const requestTimeoutMs = isDiscoveryRequest ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS) : resolveRequestTimeoutMs(context?.requestTimeoutMs);
|
|
187
250
|
const headers = {
|
|
188
251
|
...existingHeaders,
|
|
189
252
|
...traceHeaders,
|
|
190
|
-
...
|
|
191
|
-
...authToken && {
|
|
253
|
+
...customHeaders,
|
|
254
|
+
...authToken && !nativeCrossOrigin && {
|
|
192
255
|
Authorization: `Bearer ${authToken}`,
|
|
193
256
|
"x-adcp-auth": authToken
|
|
194
257
|
}
|
|
@@ -229,7 +292,7 @@ function hasTerminalTaskWithDataArtifact(response) {
|
|
|
229
292
|
if (typeof status?.state !== "string" || !TERMINAL_A2A_STATES.has(status.state)) return false;
|
|
230
293
|
return getLatestA2ADataPartFromResponse(response) !== void 0;
|
|
231
294
|
}
|
|
232
|
-
async function callA2ATool(agentUrl, toolName, parameters, authToken, debugLogs = [], pushNotificationConfig, customHeaders, signingContext, session, signal, requestTimeoutMs, fetchFn, allowPrivateIp) {
|
|
295
|
+
async function callA2ATool(agentUrl, toolName, parameters, authToken, debugLogs = [], pushNotificationConfig, customHeaders, signingContext, session, signal, requestTimeoutMs, fetchFn, allowPrivateIp, legacyCompat) {
|
|
233
296
|
return withSpan(
|
|
234
297
|
"adcp.a2a.call_tool",
|
|
235
298
|
{
|
|
@@ -244,7 +307,8 @@ async function callA2ATool(agentUrl, toolName, parameters, authToken, debugLogs
|
|
|
244
307
|
signal,
|
|
245
308
|
requestTimeoutMs,
|
|
246
309
|
fetchFn,
|
|
247
|
-
allowPrivateIp
|
|
310
|
+
allowPrivateIp,
|
|
311
|
+
legacyCompat
|
|
248
312
|
};
|
|
249
313
|
return signingContextStorage.run(
|
|
250
314
|
signingContext,
|
|
@@ -267,6 +331,19 @@ async function callA2ATool(agentUrl, toolName, parameters, authToken, debugLogs
|
|
|
267
331
|
}
|
|
268
332
|
async function callA2AToolImpl(agentUrl, toolName, parameters, authToken, debugLogs, pushNotificationConfig, context, session) {
|
|
269
333
|
try {
|
|
334
|
+
if (context.legacyCompat?.enabled === false) {
|
|
335
|
+
const { callNativeA2ATool } = await import("./a2a-native-v1.mjs");
|
|
336
|
+
return await callNativeA2ATool({
|
|
337
|
+
cardUrls: buildCardUrls(agentUrl),
|
|
338
|
+
fetchImpl: buildFetchImpl(authToken, agentUrl),
|
|
339
|
+
toolName,
|
|
340
|
+
parameters,
|
|
341
|
+
pushNotificationConfig,
|
|
342
|
+
contextId: session?.contextId,
|
|
343
|
+
taskId: session?.taskId,
|
|
344
|
+
signal: context.signal
|
|
345
|
+
});
|
|
346
|
+
}
|
|
270
347
|
const client = await getOrCreateA2AClient(
|
|
271
348
|
agentUrl,
|
|
272
349
|
authToken,
|
|
@@ -373,6 +450,7 @@ async function callA2AToolImpl(agentUrl, toolName, parameters, authToken, debugL
|
|
|
373
450
|
export {
|
|
374
451
|
callA2ATool,
|
|
375
452
|
cancelA2ATask,
|
|
376
|
-
closeA2AConnections
|
|
453
|
+
closeA2AConnections,
|
|
454
|
+
createA2AClientFromCardUrl
|
|
377
455
|
};
|
|
378
456
|
//# sourceMappingURL=a2a.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["import { fileURLToPath as __adcpFileURLToPath } from 'node:url';\nimport { dirname as __adcpDirname } from 'node:path';\nimport { createRequire as __adcpCreateRequire } from 'node:module';\nconst __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));\nconst require = __adcpCreateRequire(import.meta.url);\n// Official A2A client implementation - NO FALLBACKS\nimport { A2AClient as A2AClientImpl } from '@a2a-js/sdk/client';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { createHmac } from 'node:crypto';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\n// The A2A SDK client is used untyped: request/response shapes are validated at\n// runtime against the AdCP wire contract, not against the SDK's exported\n// types. Preserves the prior behaviour of the CommonJS `require` form.\nconst A2AClient: any = A2AClientImpl;\n\nif (!A2AClient) {\n throw new Error('A2A SDK client is required. Please install @a2a-js/sdk');\n}\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n}\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, InstanceType<typeof A2AClient>>();\nconst pendingA2AClients = new Map<string, Promise<InstanceType<typeof A2AClient>>>();\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>\n): string {\n // 64-bit Map-key disambiguator — NOT a password hash. The cached client\n // closes over the full credential, so a hypothetical hash collision still\n // sends the original credential on the wire, just possibly cache-miss\n // and reconnect. Routed via `cacheDisambiguator` (HMAC-SHA256 with empty\n // key) instead of bare `createHash` so CodeQL's\n // `js/insufficient-password-hash` heuristic doesn't misclassify the\n // dataflow — see the helper docstring for the full rationale.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const tokenSuffix = fingerprint ? `::${cacheDisambiguator(fingerprint)}` : '';\n const headersKey = headersCacheDisambiguator(customHeaders);\n const headersSuffix = headersKey ? `::headers:${headersKey}` : '';\n const signingSuffix = signingCacheKey ? `::${signingCacheKey}` : '';\n return `${agentUrl}${tokenSuffix}${headersSuffix}${signingSuffix}`;\n}\n\n/**\n * Produce a stable 64-bit Map-key disambiguator from credential material.\n * Mirrors the helper in `src/lib/protocols/mcp.ts` — the two protocol\n * modules intentionally don't share runtime imports, so each carries its\n * own copy. See the MCP-side docstring for the full rationale.\n */\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex').slice(0, 16);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheDisambiguator(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? cacheDisambiguator(JSON.stringify(entries)) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A tasks/cancel for an in-flight task (A2A 0.3.0 §7.4).\n *\n * Sends a raw JSON-RPC 2.0 POST directly to the agent endpoint with the same\n * auth header shape as `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT\n * enter `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // POST is JSON-RPC at the bare A2A endpoint. Calling this on an MCP agent\n // would POST `tasks/cancel` JSON-RPC at an MCP endpoint and 404. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const transportFetch = createAgentTransportFetch(agentUrl, { trustedFetchFn: fetchFn, allowPrivateIp });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n if (authToken) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n await client.cancelTask({ id: taskId });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<InstanceType<typeof A2AClient>> {\n const signingContext = signingContextStorage.getStore();\n const fetchFn = callContextStorage.getStore()?.fetchFn;\n const cacheKey = a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, customHeaders);\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = a2aClientCache.get(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n a2aClientCache.set(cacheKey, client);\n return client;\n })\n .finally(() => {\n pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(\n agentUrl: string,\n authToken: string | undefined\n): Promise<InstanceType<typeof A2AClient>> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: callContextStorage.getStore()?.fetchFn,\n allowPrivateIp: callContextStorage.getStore()?.allowPrivateIp,\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const urlString = typeof url === 'string' ? url : url.toString();\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...context?.customHeaders,\n ...(authToken && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states per A2A 0.3.0 §3.4. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient; see AgentClient.getContextId() / getPendingTaskId().\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n\n const requestPayload: {\n message: {\n messageId: string;\n role: string;\n kind: string;\n parts: Array<{ kind: string; data: { skill: string; parameters: Record<string, unknown> } }>;\n contextId?: string;\n taskId?: string;\n };\n configuration?: { pushNotificationConfig: PushNotificationConfig };\n } = {\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: 'user',\n kind: 'message',\n parts: [\n {\n kind: 'data',\n data: {\n skill: toolName,\n parameters: parameters,\n },\n },\n ],\n ...(session?.contextId && { contextId: session.contextId }),\n ...(session?.taskId && { taskId: session.taskId }),\n },\n };\n\n if (pushNotificationConfig) {\n requestPayload.configuration = {\n pushNotificationConfig: pushNotificationConfig,\n };\n }\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n kind: 'data',\n data: { skill: toolName, parameters: redactedParameters },\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n pushNotificationConfig: redactPushNotificationConfigForDebug(\n requestPayload.configuration.pushNotificationConfig\n )!,\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const messageResponse = await client.sendMessage(requestPayload);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, context.customHeaders));\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["require"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["import { fileURLToPath as __adcpFileURLToPath } from 'node:url';\nimport { dirname as __adcpDirname } from 'node:path';\nimport { createRequire as __adcpCreateRequire } from 'node:module';\nconst __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));\nconst require = __adcpCreateRequire(import.meta.url);\n// Official A2A client implementation - NO FALLBACKS\nimport { A2AClient as A2AClientImpl } from '@a2a-js/sdk/client';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { createHmac } from 'node:crypto';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\n// The A2A SDK client is used untyped: request/response shapes are validated at\n// runtime against the AdCP wire contract, not against the SDK's exported\n// types. Preserves the prior behaviour of the CommonJS `require` form.\nconst A2AClient: any = A2AClientImpl;\n\nif (!A2AClient) {\n throw new Error('A2A SDK client is required. Please install @a2a-js/sdk');\n}\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n legacyCompat?: A2ALegacyCompatOptions;\n}\n\n/** Controls whether A2A v0.3 compatibility is accepted. */\nexport interface A2ALegacyCompatOptions {\n enabled: boolean;\n}\n\nconst DEFAULT_A2A_LEGACY_COMPAT: Readonly<A2ALegacyCompatOptions> = Object.freeze({ enabled: true });\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, InstanceType<typeof A2AClient>>();\nconst pendingA2AClients = new Map<string, Promise<InstanceType<typeof A2AClient>>>();\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>\n): string {\n // 64-bit Map-key disambiguator — NOT a password hash. The cached client\n // closes over the full credential, so a hypothetical hash collision still\n // sends the original credential on the wire, just possibly cache-miss\n // and reconnect. Routed via `cacheDisambiguator` (HMAC-SHA256 with empty\n // key) instead of bare `createHash` so CodeQL's\n // `js/insufficient-password-hash` heuristic doesn't misclassify the\n // dataflow — see the helper docstring for the full rationale.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const tokenSuffix = fingerprint ? `::${cacheDisambiguator(fingerprint)}` : '';\n const headersKey = headersCacheDisambiguator(customHeaders);\n const headersSuffix = headersKey ? `::headers:${headersKey}` : '';\n const signingSuffix = signingCacheKey ? `::${signingCacheKey}` : '';\n return `${agentUrl}${tokenSuffix}${headersSuffix}${signingSuffix}`;\n}\n\n/**\n * Produce a stable 64-bit Map-key disambiguator from credential material.\n * Mirrors the helper in `src/lib/protocols/mcp.ts` — the two protocol\n * modules intentionally don't share runtime imports, so each carries its\n * own copy. See the MCP-side docstring for the full rationale.\n */\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex').slice(0, 16);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheDisambiguator(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? cacheDisambiguator(JSON.stringify(entries)) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A tasks/cancel for an in-flight task (A2A 0.3.0 §7.4).\n *\n * Uses the official A2A SDK cancel method with the same auth header shape as\n * `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT enter\n * `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean,\n legacyCompat: A2ALegacyCompatOptions = DEFAULT_A2A_LEGACY_COMPAT\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // POST is JSON-RPC at the bare A2A endpoint. Calling this on an MCP agent\n // would POST `tasks/cancel` JSON-RPC at an MCP endpoint and 404. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const configuredHeaders = agent.headers ?? {};\n const transportFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: fetchFn,\n allowPrivateIp,\n originBoundHeaders: Object.keys(configuredHeaders),\n crossOriginCredentialPolicy: legacyCompat.enabled === false ? 'refuse' : 'strip',\n });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n const requestUrl = new URL(input instanceof Request ? input.url : input.toString());\n const nativeCrossOrigin = legacyCompat.enabled === false && requestUrl.origin !== new URL(agentUrl).origin;\n if (nativeCrossOrigin && (authToken || agent.request_signing)) {\n const credentialHeaderNames = [\n ...(authToken ? ['authorization', 'x-adcp-auth'] : []),\n ...(agent.request_signing ? ['content-digest', 'signature', 'signature-input'] : []),\n ];\n throw new Error(\n `A2A native cancel refused credentialed cross-origin dispatch to ${requestUrl.origin}; ` +\n `credential headers: ${credentialHeaderNames.join(', ')}`\n );\n }\n if (authToken && !nativeCrossOrigin) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n if (!nativeCrossOrigin) {\n for (const [name, value] of Object.entries(configuredHeaders)) headers.set(name, value);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await createA2AClientFromCardUrl(cardUrl, fetchImpl, legacyCompat);\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n if (legacyCompat.enabled === false) {\n const { createNativeCancelTaskRequest } = await import('./a2a-native-v1');\n await client.cancelTask(createNativeCancelTaskRequest(taskId));\n } else {\n await client.cancelTask({ id: taskId });\n }\n}\n\n/**\n * Build an official A2A client from a card URL. Ordinary calls retain the\n * stable SDK's v0.3 client; native-only compliance calls use the separately\n * pinned official 1.0 client.\n */\nexport async function createA2AClientFromCardUrl(\n cardUrl: string,\n fetchImpl: typeof fetch,\n legacyCompat: A2ALegacyCompatOptions = DEFAULT_A2A_LEGACY_COMPAT\n): Promise<any> {\n if (legacyCompat.enabled === false) {\n const { createNativeA2AClientFromCardUrl } = await import('./a2a-native-v1');\n return createNativeA2AClientFromCardUrl(cardUrl, fetchImpl);\n }\n return A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<InstanceType<typeof A2AClient>> {\n const signingContext = signingContextStorage.getStore();\n const fetchFn = callContextStorage.getStore()?.fetchFn;\n const cacheKey = a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, customHeaders);\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = a2aClientCache.get(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n a2aClientCache.set(cacheKey, client);\n return client;\n })\n .finally(() => {\n pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(\n agentUrl: string,\n authToken: string | undefined\n): Promise<InstanceType<typeof A2AClient>> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const creationContext = callContextStorage.getStore();\n const originBoundCustomHeaderNames = Object.keys(creationContext?.customHeaders ?? {});\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: creationContext?.fetchFn,\n allowPrivateIp: creationContext?.allowPrivateIp,\n originBoundHeaders: originBoundCustomHeaderNames,\n crossOriginCredentialPolicy: creationContext?.legacyCompat?.enabled === false ? 'refuse' : 'strip',\n onOriginBoundHeadersStripped: (headerNames, target) => {\n callContextStorage.getStore()?.debugLogs.push({\n type: 'warning',\n message: `A2A: Stripped configured origin-bound headers (${headerNames.join(', ')}) before cross-origin dispatch to ${target.origin}`,\n timestamp: new Date().toISOString(),\n });\n },\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const urlString = typeof url === 'string' ? url : url.toString();\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const nativeCrossOrigin =\n context?.legacyCompat?.enabled === false && new URL(urlString).origin !== new URL(agentUrl).origin;\n if (nativeCrossOrigin && (authToken || signingContext)) {\n const targetOrigin = new URL(urlString).origin;\n const credentialHeaderNames = [\n ...(authToken ? ['authorization', 'x-adcp-auth'] : []),\n ...(signingContext ? ['content-digest', 'signature', 'signature-input'] : []),\n ];\n throw new Error(\n `A2A native dispatch refused credentialed cross-origin endpoint ${targetOrigin}; ` +\n `credential headers: ${credentialHeaderNames.join(', ')}`\n );\n }\n const customHeaders = nativeCrossOrigin ? undefined : context?.customHeaders;\n if (nativeCrossOrigin && Object.keys(context?.customHeaders ?? {}).length > 0) {\n context?.debugLogs.push({\n type: 'warning',\n message: `A2A: Stripped configured origin-bound headers before cross-origin dispatch to ${new URL(urlString).origin}`,\n timestamp: new Date().toISOString(),\n });\n }\n const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...customHeaders,\n ...(authToken &&\n !nativeCrossOrigin && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states per A2A 0.3.0 §3.4. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient; see AgentClient.getContextId() / getPendingTaskId().\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean,\n legacyCompat?: A2ALegacyCompatOptions\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n legacyCompat,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n if (context.legacyCompat?.enabled === false) {\n const { callNativeA2ATool } = await import('./a2a-native-v1');\n return await callNativeA2ATool({\n cardUrls: buildCardUrls(agentUrl),\n fetchImpl: buildFetchImpl(authToken, agentUrl),\n toolName,\n parameters,\n pushNotificationConfig,\n contextId: session?.contextId,\n taskId: session?.taskId,\n signal: context.signal,\n });\n }\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n\n const requestPayload: {\n message: {\n messageId: string;\n role: string;\n kind: string;\n parts: Array<{ kind: string; data: { skill: string; parameters: Record<string, unknown> } }>;\n contextId?: string;\n taskId?: string;\n };\n configuration?: { pushNotificationConfig: PushNotificationConfig };\n } = {\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: 'user',\n kind: 'message',\n parts: [\n {\n kind: 'data',\n data: {\n skill: toolName,\n parameters: parameters,\n },\n },\n ],\n ...(session?.contextId && { contextId: session.contextId }),\n ...(session?.taskId && { taskId: session.taskId }),\n },\n };\n\n if (pushNotificationConfig) {\n requestPayload.configuration = {\n pushNotificationConfig: pushNotificationConfig,\n };\n }\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n kind: 'data',\n data: { skill: toolName, parameters: redactedParameters },\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n pushNotificationConfig: redactPushNotificationConfigForDebug(\n requestPayload.configuration.pushNotificationConfig\n )!,\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const messageResponse = await client.sendMessage(requestPayload);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(a2aCacheKey(agentUrl, authToken, signingContext?.cacheKey, context.customHeaders));\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["require"]}
|
|
@@ -108,6 +108,8 @@ export interface TransportOptions {
|
|
|
108
108
|
* Set to `0` to disable the SDK-imposed discovery timeout.
|
|
109
109
|
*/
|
|
110
110
|
requestTimeoutMs?: number;
|
|
111
|
+
/** A2A-only compatibility policy. Compliance uses `{ enabled: false }` for native 1.0 grading. */
|
|
112
|
+
legacyCompat?: import('./a2a.mjs').A2ALegacyCompatOptions;
|
|
111
113
|
}
|
|
112
114
|
/**
|
|
113
115
|
* Options for {@link ProtocolClient.callTool}. All fields are optional.
|
|
@@ -207,3 +209,4 @@ export declare const createMCPClient: (agentUrl: string, authToken?: string, hea
|
|
|
207
209
|
export declare const createA2AClient: (agentUrl: string, authToken?: string, headers?: Record<string, string>, serverVersion?: "v2" | "v3", adcpVersion?: string, transport?: TransportOptions, versionEnvelopeMode?: VersionEnvelopeMode) => {
|
|
208
210
|
callTool: (toolName: string, parameters: Record<string, unknown>, debugLogs?: DebugLogEntry[]) => Promise<unknown>;
|
|
209
211
|
};
|
|
212
|
+
export type { A2ALegacyCompatOptions } from './a2a.mjs';
|