var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/client/index.ts
var client_exports = {};
__export(client_exports, {
  A2AClient: () => A2AClient,
  AgentCardResolver: () => AgentCardResolver,
  AuthenticatedExtendedCardNotConfiguredError: () => AuthenticatedExtendedCardNotConfiguredError,
  Client: () => Client,
  ClientCallContext: () => ClientCallContext,
  ClientCallContextKey: () => ClientCallContextKey,
  ClientFactory: () => ClientFactory,
  ClientFactoryOptions: () => ClientFactoryOptions,
  ContentTypeNotSupportedError: () => ContentTypeNotSupportedError,
  DefaultAgentCardResolver: () => DefaultAgentCardResolver,
  InvalidAgentResponseError: () => InvalidAgentResponseError,
  JsonRpcTransport: () => JsonRpcTransport,
  JsonRpcTransportFactory: () => JsonRpcTransportFactory,
  PushNotificationNotSupportedError: () => PushNotificationNotSupportedError,
  RestTransport: () => RestTransport,
  RestTransportFactory: () => RestTransportFactory,
  ServiceParameters: () => ServiceParameters,
  TaskNotCancelableError: () => TaskNotCancelableError,
  TaskNotFoundError: () => TaskNotFoundError,
  UnsupportedOperationError: () => UnsupportedOperationError,
  createAuthenticatingFetchWithRetry: () => createAuthenticatingFetchWithRetry,
  withA2AExtensions: () => withA2AExtensions
});
module.exports = __toCommonJS(client_exports);

// src/constants.ts
var AGENT_CARD_PATH = ".well-known/agent-card.json";
var HTTP_EXTENSION_HEADER = "X-A2A-Extensions";

// src/errors.ts
var A2A_ERROR_CODE = {
  PARSE_ERROR: -32700,
  INVALID_REQUEST: -32600,
  METHOD_NOT_FOUND: -32601,
  INVALID_PARAMS: -32602,
  INTERNAL_ERROR: -32603,
  TASK_NOT_FOUND: -32001,
  TASK_NOT_CANCELABLE: -32002,
  PUSH_NOTIFICATION_NOT_SUPPORTED: -32003,
  UNSUPPORTED_OPERATION: -32004,
  CONTENT_TYPE_NOT_SUPPORTED: -32005,
  INVALID_AGENT_RESPONSE: -32006,
  AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED: -32007
};
var TaskNotFoundError = class extends Error {
  constructor(message) {
    super(message ?? "Task not found");
    this.name = "TaskNotFoundError";
  }
};
var TaskNotCancelableError = class extends Error {
  constructor(message) {
    super(message ?? "Task cannot be canceled");
    this.name = "TaskNotCancelableError";
  }
};
var PushNotificationNotSupportedError = class extends Error {
  constructor(message) {
    super(message ?? "Push Notification is not supported");
    this.name = "PushNotificationNotSupportedError";
  }
};
var UnsupportedOperationError = class extends Error {
  constructor(message) {
    super(message ?? "This operation is not supported");
    this.name = "UnsupportedOperationError";
  }
};
var ContentTypeNotSupportedError = class extends Error {
  constructor(message) {
    super(message ?? "Incompatible content types");
    this.name = "ContentTypeNotSupportedError";
  }
};
var InvalidAgentResponseError = class extends Error {
  constructor(message) {
    super(message ?? "Invalid agent response type");
    this.name = "InvalidAgentResponseError";
  }
};
var AuthenticatedExtendedCardNotConfiguredError = class extends Error {
  constructor(message) {
    super(message ?? "Authenticated Extended Card not configured");
    this.name = "AuthenticatedExtendedCardNotConfiguredError";
  }
};

// src/sse_utils.ts
async function* parseSseStream(response) {
  if (!response.body) {
    throw new Error("SSE response body is undefined. Cannot read stream.");
  }
  let buffer = "";
  let eventType = "message";
  let eventData = "";
  const stream = response.body.pipeThrough(new TextDecoderStream());
  for await (const value of readFrom(stream)) {
    buffer += value;
    let lineEndIndex;
    while ((lineEndIndex = buffer.indexOf("\n")) >= 0) {
      const line = buffer.substring(0, lineEndIndex).trim();
      buffer = buffer.substring(lineEndIndex + 1);
      if (line === "") {
        if (eventData) {
          yield { type: eventType, data: eventData };
          eventData = "";
          eventType = "message";
        }
      } else if (line.startsWith("event:")) {
        eventType = line.substring("event:".length).trim();
      } else if (line.startsWith("data:")) {
        eventData = line.substring("data:".length).trim();
      }
    }
  }
  if (eventData) {
    yield { type: eventType, data: eventData };
  }
}
async function* readFrom(stream) {
  const reader = stream.getReader();
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        break;
      }
      yield value;
    }
  } finally {
    reader.releaseLock();
  }
}

// src/client/transports/json_rpc_transport.ts
var JsonRpcTransport = class _JsonRpcTransport {
  customFetchImpl;
  endpoint;
  requestIdCounter = 1;
  constructor(options) {
    this.endpoint = options.endpoint;
    this.customFetchImpl = options.fetchImpl;
  }
  async getExtendedAgentCard(options, idOverride) {
    const rpcResponse = await this._sendRpcRequest("agent/getAuthenticatedExtendedCard", void 0, idOverride, options);
    return rpcResponse.result;
  }
  async sendMessage(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest(
      "message/send",
      params,
      idOverride,
      options
    );
    return rpcResponse.result;
  }
  async *sendMessageStream(params, options) {
    yield* this._sendStreamingRequest("message/stream", params, options);
  }
  async setTaskPushNotificationConfig(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/set", params, idOverride, options);
    return rpcResponse.result;
  }
  async getTaskPushNotificationConfig(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/get", params, idOverride, options);
    return rpcResponse.result;
  }
  async listTaskPushNotificationConfig(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/list", params, idOverride, options);
    return rpcResponse.result;
  }
  async deleteTaskPushNotificationConfig(params, options, idOverride) {
    await this._sendRpcRequest("tasks/pushNotificationConfig/delete", params, idOverride, options);
  }
  async getTask(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest(
      "tasks/get",
      params,
      idOverride,
      options
    );
    return rpcResponse.result;
  }
  async cancelTask(params, options, idOverride) {
    const rpcResponse = await this._sendRpcRequest(
      "tasks/cancel",
      params,
      idOverride,
      options
    );
    return rpcResponse.result;
  }
  async *resubscribeTask(params, options) {
    yield* this._sendStreamingRequest("tasks/resubscribe", params, options);
  }
  async callExtensionMethod(method, params, idOverride, options) {
    return await this._sendRpcRequest(
      method,
      params,
      idOverride,
      options
    );
  }
  _fetch(...args) {
    if (this.customFetchImpl) {
      return this.customFetchImpl(...args);
    }
    if (typeof fetch === "function") {
      return fetch(...args);
    }
    throw new Error(
      "A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2ATransportOptions. "
    );
  }
  async _sendRpcRequest(method, params, idOverride, options) {
    const requestId = idOverride ?? this.requestIdCounter++;
    const rpcRequest = {
      jsonrpc: "2.0",
      method,
      params,
      id: requestId
    };
    const httpResponse = await this._fetchRpc(rpcRequest, "application/json", options);
    if (!httpResponse.ok) {
      let errorBodyText = "(empty or non-JSON response)";
      let errorJson;
      try {
        errorBodyText = await httpResponse.text();
        errorJson = JSON.parse(errorBodyText);
      } catch (e) {
        throw new Error(
          `HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`,
          { cause: e }
        );
      }
      if (errorJson.jsonrpc && errorJson.error) {
        throw _JsonRpcTransport.mapToError(errorJson);
      } else {
        throw new Error(
          `HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`
        );
      }
    }
    const rpcResponse = await httpResponse.json();
    if (rpcResponse.id !== requestId) {
      throw new Error(
        `JSON-RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}.`
      );
    }
    if ("error" in rpcResponse) {
      throw _JsonRpcTransport.mapToError(rpcResponse);
    }
    return rpcResponse;
  }
  async _fetchRpc(rpcRequest, acceptHeader = "application/json", options) {
    const requestInit = {
      method: "POST",
      headers: {
        ...options?.serviceParameters,
        "Content-Type": "application/json",
        Accept: acceptHeader
      },
      body: JSON.stringify(rpcRequest),
      signal: options?.signal
    };
    return this._fetch(this.endpoint, requestInit);
  }
  async *_sendStreamingRequest(method, params, options) {
    const clientRequestId = this.requestIdCounter++;
    const rpcRequest = {
      jsonrpc: "2.0",
      method,
      params,
      id: clientRequestId
    };
    const response = await this._fetchRpc(rpcRequest, "text/event-stream", options);
    if (!response.ok) {
      let errorBody = "";
      let errorJson;
      try {
        errorBody = await response.text();
        errorJson = JSON.parse(errorBody);
      } catch (e) {
        throw new Error(
          `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`,
          { cause: e }
        );
      }
      if (errorJson.error) {
        throw new Error(
          `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`
        );
      }
      throw new Error(
        `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}`
      );
    }
    if (!response.headers.get("Content-Type")?.startsWith("text/event-stream")) {
      throw new Error(
        `Invalid response Content-Type for SSE stream for ${method}. Expected 'text/event-stream'.`
      );
    }
    for await (const event of parseSseStream(response)) {
      yield this._processSseEventData(event.data, clientRequestId);
    }
  }
  _processSseEventData(jsonData, originalRequestId) {
    if (!jsonData.trim()) {
      throw new Error("Attempted to process empty SSE event data.");
    }
    let a2aStreamResponse;
    try {
      a2aStreamResponse = JSON.parse(jsonData);
    } catch (e) {
      throw new Error(
        `Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e instanceof Error && e.message || "Unknown error"}`,
        { cause: e }
      );
    }
    if (a2aStreamResponse.id !== originalRequestId) {
      throw new Error(
        `JSON-RPC response ID mismatch in SSE event. Expected ${originalRequestId}, got ${a2aStreamResponse.id}.`
      );
    }
    if ("error" in a2aStreamResponse) {
      const err = a2aStreamResponse.error;
      throw new Error(
        `SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data || {})}`,
        { cause: _JsonRpcTransport.mapToError(a2aStreamResponse) }
      );
    }
    if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
      throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
    }
    return a2aStreamResponse.result;
  }
  static mapToError(response) {
    switch (response.error.code) {
      case -32001:
        return new TaskNotFoundJSONRPCError(response);
      case -32002:
        return new TaskNotCancelableJSONRPCError(response);
      case -32003:
        return new PushNotificationNotSupportedJSONRPCError(response);
      case -32004:
        return new UnsupportedOperationJSONRPCError(response);
      case -32005:
        return new ContentTypeNotSupportedJSONRPCError(response);
      case -32006:
        return new InvalidAgentResponseJSONRPCError(response);
      case -32007:
        return new AuthenticatedExtendedCardNotConfiguredJSONRPCError(response);
      default:
        return new JSONRPCTransportError(response);
    }
  }
};
var JsonRpcTransportFactory = class _JsonRpcTransportFactory {
  constructor(options) {
    this.options = options;
  }
  static name = "JSONRPC";
  get protocolName() {
    return _JsonRpcTransportFactory.name;
  }
  async create(url, _agentCard) {
    return new JsonRpcTransport({
      endpoint: url,
      fetchImpl: this.options?.fetchImpl
    });
  }
};
var JSONRPCTransportError = class extends Error {
  constructor(errorResponse) {
    super(
      `JSON-RPC error: ${errorResponse.error.message} (Code: ${errorResponse.error.code}) Data: ${JSON.stringify(errorResponse.error.data || {})}`
    );
    this.errorResponse = errorResponse;
  }
};
var TaskNotFoundJSONRPCError = class extends TaskNotFoundError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var TaskNotCancelableJSONRPCError = class extends TaskNotCancelableError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var PushNotificationNotSupportedJSONRPCError = class extends PushNotificationNotSupportedError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var UnsupportedOperationJSONRPCError = class extends UnsupportedOperationError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var ContentTypeNotSupportedJSONRPCError = class extends ContentTypeNotSupportedError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var InvalidAgentResponseJSONRPCError = class extends InvalidAgentResponseError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};
var AuthenticatedExtendedCardNotConfiguredJSONRPCError = class extends AuthenticatedExtendedCardNotConfiguredError {
  constructor(errorResponse) {
    super();
    this.errorResponse = errorResponse;
  }
};

// src/client/client.ts
var A2AClient = class _A2AClient {
  static emptyOptions = void 0;
  agentCardPromise;
  customFetchImpl;
  serviceEndpointUrl;
  // To be populated from AgentCard after fetchin
  // A2AClient is built around JSON-RPC types, so it will only support JSON-RPC transport, new client with transport agnostic interface is going to be created for multi-transport.
  // New transport abstraction isn't going to expose individual transport specific fields, so to keep returning JSON-RPC IDs here for compatibility,
  // keep counter here and pass it to JsonRpcTransport via an optional idOverride parameter (which is not visible via transport-agnostic A2ATransport interface).
  transport;
  requestIdCounter = 1;
  /**
   * Constructs an A2AClient instance from an AgentCard.
   * @param agentCard The AgentCard object.
   * @param options Optional. The options for the A2AClient including the fetch/auth implementation.
   */
  constructor(agentCard, options) {
    this.customFetchImpl = options?.fetchImpl;
    if (typeof agentCard === "string") {
      console.warn(
        "Warning: Constructing A2AClient with a URL is deprecated. Please use A2AClient.fromCardUrl() instead."
      );
      this.agentCardPromise = this._fetchAndCacheAgentCard(agentCard, options?.agentCardPath);
    } else {
      if (!agentCard.url) {
        throw new Error(
          "Provided Agent Card does not contain a valid 'url' for the service endpoint."
        );
      }
      this.serviceEndpointUrl = agentCard.url;
      this.agentCardPromise = Promise.resolve(agentCard);
    }
  }
  /**
   * Dynamically resolves the fetch implementation to use for requests.
   * Prefers a custom implementation if provided, otherwise falls back to the global fetch.
   * @returns The fetch implementation.
   * @param args Arguments to pass to the fetch implementation.
   * @throws If no fetch implementation is available.
   */
  _fetch(...args) {
    if (this.customFetchImpl) {
      return this.customFetchImpl(...args);
    }
    if (typeof fetch === "function") {
      return fetch(...args);
    }
    throw new Error(
      "A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2AClientOptions. For earlier Node.js versions (pre-v18), you can use a library like `node-fetch`."
    );
  }
  /**
   * Creates an A2AClient instance by fetching the AgentCard from a URL then constructing the A2AClient.
   * @param agentCardUrl The URL of the agent card.
   * @param options Optional. The options for the A2AClient including the fetch/auth implementation.
   * @returns A Promise that resolves to a new A2AClient instance.
   */
  static async fromCardUrl(agentCardUrl, options) {
    const fetchImpl = options?.fetchImpl;
    const requestInit = {
      headers: { Accept: "application/json" }
    };
    let response;
    if (fetchImpl) {
      response = await fetchImpl(agentCardUrl, requestInit);
    } else if (typeof fetch === "function") {
      response = await fetch(agentCardUrl, requestInit);
    } else {
      throw new Error(
        "A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2AClientOptions. For earlier Node.js versions (pre-v18), you can use a library like `node-fetch`."
      );
    }
    if (!response.ok) {
      throw new Error(
        `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
      );
    }
    let agentCard;
    try {
      agentCard = await response.json();
    } catch (error) {
      console.error("Failed to parse Agent Card JSON:", error);
      throw new Error(
        `Failed to parse Agent Card JSON from ${agentCardUrl}. Original error: ${error.message}`
      );
    }
    return new _A2AClient(agentCard, options);
  }
  /**
   * Sends a message to the agent.
   * The behavior (blocking/non-blocking) and push notification configuration
   * are specified within the `params.configuration` object.
   * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
   * @param params The parameters for sending the message, including the message content and configuration.
   * @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
   */
  async sendMessage(params) {
    return await this.invokeJsonRpc(
      (t, p, id) => t.sendMessage(p, _A2AClient.emptyOptions, id),
      params
    );
  }
  /**
   * Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
   * Push notification configuration can be specified in `params.configuration`.
   * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
   * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
   * @param params The parameters for sending the message.
   * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
   * The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
   */
  async *sendMessageStream(params) {
    const agentCard = await this.agentCardPromise;
    if (!agentCard.capabilities?.streaming) {
      throw new Error(
        "Agent does not support streaming (AgentCard.capabilities.streaming is not true)."
      );
    }
    const transport = await this._getOrCreateTransport();
    yield* transport.sendMessageStream(params);
  }
  /**
   * Sets or updates the push notification configuration for a given task.
   * Requires the agent to support push notifications (`capabilities.pushNotifications: true` in AgentCard).
   * @param params Parameters containing the taskId and the TaskPushNotificationConfig.
   * @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
   */
  async setTaskPushNotificationConfig(params) {
    const agentCard = await this.agentCardPromise;
    if (!agentCard.capabilities?.pushNotifications) {
      throw new Error(
        "Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true)."
      );
    }
    return await this.invokeJsonRpc((t, p, id) => t.setTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
  }
  /**
   * Gets the push notification configuration for a given task.
   * @param params Parameters containing the taskId.
   * @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
   */
  async getTaskPushNotificationConfig(params) {
    return await this.invokeJsonRpc(
      (t, p, id) => t.getTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id),
      params
    );
  }
  /**
   * Lists the push notification configurations for a given task.
   * @param params Parameters containing the taskId.
   * @returns A Promise resolving to ListTaskPushNotificationConfigResponse.
   */
  async listTaskPushNotificationConfig(params) {
    return await this.invokeJsonRpc((t, p, id) => t.listTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
  }
  /**
   * Deletes the push notification configuration for a given task.
   * @param params Parameters containing the taskId and push notification configuration ID.
   * @returns A Promise resolving to DeleteTaskPushNotificationConfigResponse.
   */
  async deleteTaskPushNotificationConfig(params) {
    return await this.invokeJsonRpc((t, p, id) => t.deleteTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
  }
  /**
   * Retrieves a task by its ID.
   * @param params Parameters containing the taskId and optional historyLength.
   * @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
   */
  async getTask(params) {
    return await this.invokeJsonRpc(
      (t, p, id) => t.getTask(p, _A2AClient.emptyOptions, id),
      params
    );
  }
  /**
   * Cancels a task by its ID.
   * @param params Parameters containing the taskId.
   * @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
   */
  async cancelTask(params) {
    return await this.invokeJsonRpc(
      (t, p, id) => t.cancelTask(p, _A2AClient.emptyOptions, id),
      params
    );
  }
  /**
   * @template TExtensionParams The type of parameters for the custom extension method.
   * @template TExtensionResponse The type of response expected from the custom extension method.
   * This should extend JSONRPCResponse. This ensures the extension response is still a valid A2A response.
   * @param method Custom JSON-RPC method defined in the AgentCard's extensions.
   * @param params Extension paramters defined in the AgentCard's extensions.
   * @returns A Promise that resolves to the RPC response.
   */
  async callExtensionMethod(method, params) {
    const transport = await this._getOrCreateTransport();
    try {
      return await transport.callExtensionMethod(
        method,
        params,
        this.requestIdCounter++
      );
    } catch (e) {
      const errorResponse = extractJSONRPCError(e);
      if (errorResponse) {
        return errorResponse;
      }
      throw e;
    }
  }
  /**
   * Resubscribes to a task's event stream using Server-Sent Events (SSE).
   * This is used if a previous SSE connection for an active task was broken.
   * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
   * @param params Parameters containing the taskId.
   * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
   */
  async *resubscribeTask(params) {
    const agentCard = await this.agentCardPromise;
    if (!agentCard.capabilities?.streaming) {
      throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
    }
    const transport = await this._getOrCreateTransport();
    yield* transport.resubscribeTask(params);
  }
  ////////////////////////////////////////////////////////////////////////////////
  // Functions used to support old A2AClient Constructor to be deprecated soon
  // TODOs:
  // * remove `agentCardPromise`, and just use agentCard initialized
  // * _getServiceEndpoint can be made synchronous or deleted and accessed via
  //   agentCard.url
  // * getAgentCard changed to this.agentCard
  // * delete resolveAgentCardUrl(), _fetchAndCacheAgentCard(),
  //   agentCardPath from A2AClientOptions
  // * delete _getOrCreateTransport
  ////////////////////////////////////////////////////////////////////////////////
  async _getOrCreateTransport() {
    if (this.transport) {
      return this.transport;
    }
    const endpoint = await this._getServiceEndpoint();
    this.transport = new JsonRpcTransport({ fetchImpl: this.customFetchImpl, endpoint });
    return this.transport;
  }
  /**
   * Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
   * This method is called by the constructor.
   * @param agentBaseUrl The base URL of the A2A agent (e.g., https://agent.example.com)
   * @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
   * @returns A Promise that resolves to the AgentCard.
   */
  async _fetchAndCacheAgentCard(agentBaseUrl, agentCardPath) {
    try {
      const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
      const response = await this._fetch(agentCardUrl, {
        headers: { Accept: "application/json" }
      });
      if (!response.ok) {
        throw new Error(
          `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
        );
      }
      const agentCard = await response.json();
      if (!agentCard.url) {
        throw new Error(
          "Fetched Agent Card does not contain a valid 'url' for the service endpoint."
        );
      }
      this.serviceEndpointUrl = agentCard.url;
      return agentCard;
    } catch (error) {
      console.error("Error fetching or parsing Agent Card:", error);
      throw error;
    }
  }
  /**
   * Retrieves the Agent Card.
   * If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
   * Otherwise, it returns the card fetched and cached during client construction.
   * @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
   * @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
   * If provided, this will fetch a new card, not use the cached one from the constructor's URL.
   * @returns A Promise that resolves to the AgentCard.
   */
  async getAgentCard(agentBaseUrl, agentCardPath) {
    if (agentBaseUrl) {
      const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
      const response = await this._fetch(agentCardUrl, {
        headers: { Accept: "application/json" }
      });
      if (!response.ok) {
        throw new Error(
          `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
        );
      }
      return await response.json();
    }
    return this.agentCardPromise;
  }
  /**
   * Determines the agent card URL based on the agent URL.
   * @param agentBaseUrl The agent URL.
   * @param agentCardPath Optional relative path to the agent card, defaults to .well-known/agent-card.json
   */
  resolveAgentCardUrl(agentBaseUrl, agentCardPath = AGENT_CARD_PATH) {
    return `${agentBaseUrl.replace(/\/$/, "")}/${agentCardPath.replace(/^\//, "")}`;
  }
  /**
   * Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
   * @returns A Promise that resolves to the service endpoint URL string.
   */
  async _getServiceEndpoint() {
    if (this.serviceEndpointUrl) {
      return this.serviceEndpointUrl;
    }
    await this.agentCardPromise;
    if (!this.serviceEndpointUrl) {
      throw new Error(
        "Agent Card URL for RPC endpoint is not available. Fetching might have failed."
      );
    }
    return this.serviceEndpointUrl;
  }
  async invokeJsonRpc(caller, params) {
    const transport = await this._getOrCreateTransport();
    const requestId = this.requestIdCounter++;
    try {
      const result = await caller(transport, params, requestId);
      return {
        id: requestId,
        jsonrpc: "2.0",
        result: result ?? null
        // JSON-RPC requires result property on success, it will be null for "void" methods.
      };
    } catch (e) {
      const errorResponse = extractJSONRPCError(e);
      if (errorResponse) {
        return errorResponse;
      }
      throw e;
    }
  }
};
function extractJSONRPCError(error) {
  if (error instanceof Object && "errorResponse" in error && error.errorResponse instanceof Object && "jsonrpc" in error.errorResponse && error.errorResponse.jsonrpc === "2.0" && "error" in error.errorResponse && error.errorResponse.error !== null) {
    return error.errorResponse;
  } else {
    return void 0;
  }
}

// src/client/auth-handler.ts
function createAuthenticatingFetchWithRetry(fetchImpl, authHandler) {
  async function authFetch(url, init) {
    const authHeaders = await authHandler.headers() || {};
    const mergedInit = {
      ...init || {},
      headers: {
        ...authHeaders,
        ...init?.headers || {}
      }
    };
    let response = await fetchImpl(url, mergedInit);
    const updatedHeaders = await authHandler.shouldRetryWithHeaders(mergedInit, response);
    if (updatedHeaders) {
      const retryInit = {
        ...init || {},
        headers: {
          ...updatedHeaders,
          ...init?.headers || {}
        }
      };
      response = await fetchImpl(url, retryInit);
      if (response.ok && authHandler.onSuccessfulRetry) {
        await authHandler.onSuccessfulRetry(updatedHeaders);
      }
    }
    return response;
  }
  Object.setPrototypeOf(authFetch, Object.getPrototypeOf(fetchImpl));
  Object.defineProperties(authFetch, Object.getOwnPropertyDescriptors(fetchImpl));
  return authFetch;
}

// src/types/pb/a2a_types.ts
function taskStateFromJSON(object) {
  switch (object) {
    case 0:
    case "TASK_STATE_UNSPECIFIED":
      return 0 /* TASK_STATE_UNSPECIFIED */;
    case 1:
    case "TASK_STATE_SUBMITTED":
      return 1 /* TASK_STATE_SUBMITTED */;
    case 2:
    case "TASK_STATE_WORKING":
      return 2 /* TASK_STATE_WORKING */;
    case 3:
    case "TASK_STATE_COMPLETED":
      return 3 /* TASK_STATE_COMPLETED */;
    case 4:
    case "TASK_STATE_FAILED":
      return 4 /* TASK_STATE_FAILED */;
    case 5:
    case "TASK_STATE_CANCELLED":
      return 5 /* TASK_STATE_CANCELLED */;
    case 6:
    case "TASK_STATE_INPUT_REQUIRED":
      return 6 /* TASK_STATE_INPUT_REQUIRED */;
    case 7:
    case "TASK_STATE_REJECTED":
      return 7 /* TASK_STATE_REJECTED */;
    case 8:
    case "TASK_STATE_AUTH_REQUIRED":
      return 8 /* TASK_STATE_AUTH_REQUIRED */;
    case -1:
    case "UNRECOGNIZED":
    default:
      return -1 /* UNRECOGNIZED */;
  }
}
function taskStateToJSON(object) {
  switch (object) {
    case 0 /* TASK_STATE_UNSPECIFIED */:
      return "TASK_STATE_UNSPECIFIED";
    case 1 /* TASK_STATE_SUBMITTED */:
      return "TASK_STATE_SUBMITTED";
    case 2 /* TASK_STATE_WORKING */:
      return "TASK_STATE_WORKING";
    case 3 /* TASK_STATE_COMPLETED */:
      return "TASK_STATE_COMPLETED";
    case 4 /* TASK_STATE_FAILED */:
      return "TASK_STATE_FAILED";
    case 5 /* TASK_STATE_CANCELLED */:
      return "TASK_STATE_CANCELLED";
    case 6 /* TASK_STATE_INPUT_REQUIRED */:
      return "TASK_STATE_INPUT_REQUIRED";
    case 7 /* TASK_STATE_REJECTED */:
      return "TASK_STATE_REJECTED";
    case 8 /* TASK_STATE_AUTH_REQUIRED */:
      return "TASK_STATE_AUTH_REQUIRED";
    case -1 /* UNRECOGNIZED */:
    default:
      return "UNRECOGNIZED";
  }
}
function roleFromJSON(object) {
  switch (object) {
    case 0:
    case "ROLE_UNSPECIFIED":
      return 0 /* ROLE_UNSPECIFIED */;
    case 1:
    case "ROLE_USER":
      return 1 /* ROLE_USER */;
    case 2:
    case "ROLE_AGENT":
      return 2 /* ROLE_AGENT */;
    case -1:
    case "UNRECOGNIZED":
    default:
      return -1 /* UNRECOGNIZED */;
  }
}
function roleToJSON(object) {
  switch (object) {
    case 0 /* ROLE_UNSPECIFIED */:
      return "ROLE_UNSPECIFIED";
    case 1 /* ROLE_USER */:
      return "ROLE_USER";
    case 2 /* ROLE_AGENT */:
      return "ROLE_AGENT";
    case -1 /* UNRECOGNIZED */:
    default:
      return "UNRECOGNIZED";
  }
}
var SendMessageConfiguration = {
  fromJSON(object) {
    return {
      acceptedOutputModes: globalThis.Array.isArray(object?.acceptedOutputModes) ? object.acceptedOutputModes.map((e) => globalThis.String(e)) : globalThis.Array.isArray(object?.accepted_output_modes) ? object.accepted_output_modes.map(
        (e) => globalThis.String(e)
      ) : [],
      pushNotification: isSet(object.pushNotification) ? PushNotificationConfig.fromJSON(object.pushNotification) : isSet(object.push_notification) ? PushNotificationConfig.fromJSON(object.push_notification) : void 0,
      historyLength: isSet(object.historyLength) ? globalThis.Number(object.historyLength) : isSet(object.history_length) ? globalThis.Number(object.history_length) : 0,
      blocking: isSet(object.blocking) ? globalThis.Boolean(object.blocking) : false
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.acceptedOutputModes?.length) {
      obj.acceptedOutputModes = message.acceptedOutputModes;
    }
    if (message.pushNotification !== void 0) {
      obj.pushNotification = PushNotificationConfig.toJSON(message.pushNotification);
    }
    if (message.historyLength !== 0) {
      obj.historyLength = Math.round(message.historyLength);
    }
    if (message.blocking !== false) {
      obj.blocking = message.blocking;
    }
    return obj;
  }
};
var Task = {
  fromJSON(object) {
    return {
      id: isSet(object.id) ? globalThis.String(object.id) : "",
      contextId: isSet(object.contextId) ? globalThis.String(object.contextId) : isSet(object.context_id) ? globalThis.String(object.context_id) : "",
      status: isSet(object.status) ? TaskStatus.fromJSON(object.status) : void 0,
      artifacts: globalThis.Array.isArray(object?.artifacts) ? object.artifacts.map((e) => Artifact.fromJSON(e)) : [],
      history: globalThis.Array.isArray(object?.history) ? object.history.map((e) => Message.fromJSON(e)) : [],
      metadata: isObject(object.metadata) ? object.metadata : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.id !== "") {
      obj.id = message.id;
    }
    if (message.contextId !== "") {
      obj.contextId = message.contextId;
    }
    if (message.status !== void 0) {
      obj.status = TaskStatus.toJSON(message.status);
    }
    if (message.artifacts?.length) {
      obj.artifacts = message.artifacts.map((e) => Artifact.toJSON(e));
    }
    if (message.history?.length) {
      obj.history = message.history.map((e) => Message.toJSON(e));
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    return obj;
  }
};
var TaskStatus = {
  fromJSON(object) {
    return {
      state: isSet(object.state) ? taskStateFromJSON(object.state) : 0,
      update: isSet(object.message) ? Message.fromJSON(object.message) : isSet(object.update) ? Message.fromJSON(object.update) : void 0,
      timestamp: isSet(object.timestamp) ? globalThis.String(object.timestamp) : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.state !== 0) {
      obj.state = taskStateToJSON(message.state);
    }
    if (message.update !== void 0) {
      obj.message = Message.toJSON(message.update);
    }
    if (message.timestamp !== void 0) {
      obj.timestamp = message.timestamp;
    }
    return obj;
  }
};
var Part = {
  fromJSON(object) {
    return {
      part: isSet(object.text) ? { $case: "text", value: globalThis.String(object.text) } : isSet(object.file) ? { $case: "file", value: FilePart.fromJSON(object.file) } : isSet(object.data) ? { $case: "data", value: DataPart.fromJSON(object.data) } : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.part?.$case === "text") {
      obj.text = message.part.value;
    } else if (message.part?.$case === "file") {
      obj.file = FilePart.toJSON(message.part.value);
    } else if (message.part?.$case === "data") {
      obj.data = DataPart.toJSON(message.part.value);
    }
    return obj;
  }
};
var FilePart = {
  fromJSON(object) {
    return {
      file: isSet(object.fileWithUri) ? { $case: "fileWithUri", value: globalThis.String(object.fileWithUri) } : isSet(object.file_with_uri) ? { $case: "fileWithUri", value: globalThis.String(object.file_with_uri) } : isSet(object.fileWithBytes) ? { $case: "fileWithBytes", value: Buffer.from(bytesFromBase64(object.fileWithBytes)) } : isSet(object.file_with_bytes) ? { $case: "fileWithBytes", value: Buffer.from(bytesFromBase64(object.file_with_bytes)) } : void 0,
      mimeType: isSet(object.mimeType) ? globalThis.String(object.mimeType) : isSet(object.mime_type) ? globalThis.String(object.mime_type) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.file?.$case === "fileWithUri") {
      obj.fileWithUri = message.file.value;
    } else if (message.file?.$case === "fileWithBytes") {
      obj.fileWithBytes = base64FromBytes(message.file.value);
    }
    if (message.mimeType !== "") {
      obj.mimeType = message.mimeType;
    }
    return obj;
  }
};
var DataPart = {
  fromJSON(object) {
    return { data: isObject(object.data) ? object.data : void 0 };
  },
  toJSON(message) {
    const obj = {};
    if (message.data !== void 0) {
      obj.data = message.data;
    }
    return obj;
  }
};
var Message = {
  fromJSON(object) {
    return {
      messageId: isSet(object.messageId) ? globalThis.String(object.messageId) : isSet(object.message_id) ? globalThis.String(object.message_id) : "",
      contextId: isSet(object.contextId) ? globalThis.String(object.contextId) : isSet(object.context_id) ? globalThis.String(object.context_id) : "",
      taskId: isSet(object.taskId) ? globalThis.String(object.taskId) : isSet(object.task_id) ? globalThis.String(object.task_id) : "",
      role: isSet(object.role) ? roleFromJSON(object.role) : 0,
      content: globalThis.Array.isArray(object?.content) ? object.content.map((e) => Part.fromJSON(e)) : [],
      metadata: isObject(object.metadata) ? object.metadata : void 0,
      extensions: globalThis.Array.isArray(object?.extensions) ? object.extensions.map((e) => globalThis.String(e)) : []
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.messageId !== "") {
      obj.messageId = message.messageId;
    }
    if (message.contextId !== "") {
      obj.contextId = message.contextId;
    }
    if (message.taskId !== "") {
      obj.taskId = message.taskId;
    }
    if (message.role !== 0) {
      obj.role = roleToJSON(message.role);
    }
    if (message.content?.length) {
      obj.content = message.content.map((e) => Part.toJSON(e));
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    if (message.extensions?.length) {
      obj.extensions = message.extensions;
    }
    return obj;
  }
};
var Artifact = {
  fromJSON(object) {
    return {
      artifactId: isSet(object.artifactId) ? globalThis.String(object.artifactId) : isSet(object.artifact_id) ? globalThis.String(object.artifact_id) : "",
      name: isSet(object.name) ? globalThis.String(object.name) : "",
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      parts: globalThis.Array.isArray(object?.parts) ? object.parts.map((e) => Part.fromJSON(e)) : [],
      metadata: isObject(object.metadata) ? object.metadata : void 0,
      extensions: globalThis.Array.isArray(object?.extensions) ? object.extensions.map((e) => globalThis.String(e)) : []
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.artifactId !== "") {
      obj.artifactId = message.artifactId;
    }
    if (message.name !== "") {
      obj.name = message.name;
    }
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.parts?.length) {
      obj.parts = message.parts.map((e) => Part.toJSON(e));
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    if (message.extensions?.length) {
      obj.extensions = message.extensions;
    }
    return obj;
  }
};
var TaskStatusUpdateEvent = {
  fromJSON(object) {
    return {
      taskId: isSet(object.taskId) ? globalThis.String(object.taskId) : isSet(object.task_id) ? globalThis.String(object.task_id) : "",
      contextId: isSet(object.contextId) ? globalThis.String(object.contextId) : isSet(object.context_id) ? globalThis.String(object.context_id) : "",
      status: isSet(object.status) ? TaskStatus.fromJSON(object.status) : void 0,
      final: isSet(object.final) ? globalThis.Boolean(object.final) : false,
      metadata: isObject(object.metadata) ? object.metadata : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.taskId !== "") {
      obj.taskId = message.taskId;
    }
    if (message.contextId !== "") {
      obj.contextId = message.contextId;
    }
    if (message.status !== void 0) {
      obj.status = TaskStatus.toJSON(message.status);
    }
    if (message.final !== false) {
      obj.final = message.final;
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    return obj;
  }
};
var TaskArtifactUpdateEvent = {
  fromJSON(object) {
    return {
      taskId: isSet(object.taskId) ? globalThis.String(object.taskId) : isSet(object.task_id) ? globalThis.String(object.task_id) : "",
      contextId: isSet(object.contextId) ? globalThis.String(object.contextId) : isSet(object.context_id) ? globalThis.String(object.context_id) : "",
      artifact: isSet(object.artifact) ? Artifact.fromJSON(object.artifact) : void 0,
      append: isSet(object.append) ? globalThis.Boolean(object.append) : false,
      lastChunk: isSet(object.lastChunk) ? globalThis.Boolean(object.lastChunk) : isSet(object.last_chunk) ? globalThis.Boolean(object.last_chunk) : false,
      metadata: isObject(object.metadata) ? object.metadata : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.taskId !== "") {
      obj.taskId = message.taskId;
    }
    if (message.contextId !== "") {
      obj.contextId = message.contextId;
    }
    if (message.artifact !== void 0) {
      obj.artifact = Artifact.toJSON(message.artifact);
    }
    if (message.append !== false) {
      obj.append = message.append;
    }
    if (message.lastChunk !== false) {
      obj.lastChunk = message.lastChunk;
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    return obj;
  }
};
var PushNotificationConfig = {
  fromJSON(object) {
    return {
      id: isSet(object.id) ? globalThis.String(object.id) : "",
      url: isSet(object.url) ? globalThis.String(object.url) : "",
      token: isSet(object.token) ? globalThis.String(object.token) : "",
      authentication: isSet(object.authentication) ? AuthenticationInfo.fromJSON(object.authentication) : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.id !== "") {
      obj.id = message.id;
    }
    if (message.url !== "") {
      obj.url = message.url;
    }
    if (message.token !== "") {
      obj.token = message.token;
    }
    if (message.authentication !== void 0) {
      obj.authentication = AuthenticationInfo.toJSON(message.authentication);
    }
    return obj;
  }
};
var AuthenticationInfo = {
  fromJSON(object) {
    return {
      schemes: globalThis.Array.isArray(object?.schemes) ? object.schemes.map((e) => globalThis.String(e)) : [],
      credentials: isSet(object.credentials) ? globalThis.String(object.credentials) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.schemes?.length) {
      obj.schemes = message.schemes;
    }
    if (message.credentials !== "") {
      obj.credentials = message.credentials;
    }
    return obj;
  }
};
var AgentInterface = {
  fromJSON(object) {
    return {
      url: isSet(object.url) ? globalThis.String(object.url) : "",
      transport: isSet(object.transport) ? globalThis.String(object.transport) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.url !== "") {
      obj.url = message.url;
    }
    if (message.transport !== "") {
      obj.transport = message.transport;
    }
    return obj;
  }
};
var AgentCard = {
  fromJSON(object) {
    return {
      protocolVersion: isSet(object.protocolVersion) ? globalThis.String(object.protocolVersion) : isSet(object.protocol_version) ? globalThis.String(object.protocol_version) : "",
      name: isSet(object.name) ? globalThis.String(object.name) : "",
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      url: isSet(object.url) ? globalThis.String(object.url) : "",
      preferredTransport: isSet(object.preferredTransport) ? globalThis.String(object.preferredTransport) : isSet(object.preferred_transport) ? globalThis.String(object.preferred_transport) : "",
      additionalInterfaces: globalThis.Array.isArray(object?.additionalInterfaces) ? object.additionalInterfaces.map((e) => AgentInterface.fromJSON(e)) : globalThis.Array.isArray(object?.additional_interfaces) ? object.additional_interfaces.map((e) => AgentInterface.fromJSON(e)) : [],
      provider: isSet(object.provider) ? AgentProvider.fromJSON(object.provider) : void 0,
      version: isSet(object.version) ? globalThis.String(object.version) : "",
      documentationUrl: isSet(object.documentationUrl) ? globalThis.String(object.documentationUrl) : isSet(object.documentation_url) ? globalThis.String(object.documentation_url) : "",
      capabilities: isSet(object.capabilities) ? AgentCapabilities.fromJSON(object.capabilities) : void 0,
      securitySchemes: isObject(object.securitySchemes) ? globalThis.Object.entries(object.securitySchemes).reduce(
        (acc, [key, value]) => {
          acc[key] = SecurityScheme.fromJSON(value);
          return acc;
        },
        {}
      ) : isObject(object.security_schemes) ? globalThis.Object.entries(object.security_schemes).reduce(
        (acc, [key, value]) => {
          acc[key] = SecurityScheme.fromJSON(value);
          return acc;
        },
        {}
      ) : {},
      security: globalThis.Array.isArray(object?.security) ? object.security.map((e) => Security.fromJSON(e)) : [],
      defaultInputModes: globalThis.Array.isArray(object?.defaultInputModes) ? object.defaultInputModes.map((e) => globalThis.String(e)) : globalThis.Array.isArray(object?.default_input_modes) ? object.default_input_modes.map((e) => globalThis.String(e)) : [],
      defaultOutputModes: globalThis.Array.isArray(object?.defaultOutputModes) ? object.defaultOutputModes.map((e) => globalThis.String(e)) : globalThis.Array.isArray(object?.default_output_modes) ? object.default_output_modes.map((e) => globalThis.String(e)) : [],
      skills: globalThis.Array.isArray(object?.skills) ? object.skills.map((e) => AgentSkill.fromJSON(e)) : [],
      supportsAuthenticatedExtendedCard: isSet(object.supportsAuthenticatedExtendedCard) ? globalThis.Boolean(object.supportsAuthenticatedExtendedCard) : isSet(object.supports_authenticated_extended_card) ? globalThis.Boolean(object.supports_authenticated_extended_card) : false,
      signatures: globalThis.Array.isArray(object?.signatures) ? object.signatures.map((e) => AgentCardSignature.fromJSON(e)) : []
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.protocolVersion !== "") {
      obj.protocolVersion = message.protocolVersion;
    }
    if (message.name !== "") {
      obj.name = message.name;
    }
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.url !== "") {
      obj.url = message.url;
    }
    if (message.preferredTransport !== "") {
      obj.preferredTransport = message.preferredTransport;
    }
    if (message.additionalInterfaces?.length) {
      obj.additionalInterfaces = message.additionalInterfaces.map((e) => AgentInterface.toJSON(e));
    }
    if (message.provider !== void 0) {
      obj.provider = AgentProvider.toJSON(message.provider);
    }
    if (message.version !== "") {
      obj.version = message.version;
    }
    if (message.documentationUrl !== "") {
      obj.documentationUrl = message.documentationUrl;
    }
    if (message.capabilities !== void 0) {
      obj.capabilities = AgentCapabilities.toJSON(message.capabilities);
    }
    if (message.securitySchemes) {
      const entries = globalThis.Object.entries(message.securitySchemes);
      if (entries.length > 0) {
        obj.securitySchemes = {};
        entries.forEach(([k, v]) => {
          obj.securitySchemes[k] = SecurityScheme.toJSON(v);
        });
      }
    }
    if (message.security?.length) {
      obj.security = message.security.map((e) => Security.toJSON(e));
    }
    if (message.defaultInputModes?.length) {
      obj.defaultInputModes = message.defaultInputModes;
    }
    if (message.defaultOutputModes?.length) {
      obj.defaultOutputModes = message.defaultOutputModes;
    }
    if (message.skills?.length) {
      obj.skills = message.skills.map((e) => AgentSkill.toJSON(e));
    }
    if (message.supportsAuthenticatedExtendedCard !== false) {
      obj.supportsAuthenticatedExtendedCard = message.supportsAuthenticatedExtendedCard;
    }
    if (message.signatures?.length) {
      obj.signatures = message.signatures.map((e) => AgentCardSignature.toJSON(e));
    }
    return obj;
  }
};
var AgentProvider = {
  fromJSON(object) {
    return {
      url: isSet(object.url) ? globalThis.String(object.url) : "",
      organization: isSet(object.organization) ? globalThis.String(object.organization) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.url !== "") {
      obj.url = message.url;
    }
    if (message.organization !== "") {
      obj.organization = message.organization;
    }
    return obj;
  }
};
var AgentCapabilities = {
  fromJSON(object) {
    return {
      streaming: isSet(object.streaming) ? globalThis.Boolean(object.streaming) : false,
      pushNotifications: isSet(object.pushNotifications) ? globalThis.Boolean(object.pushNotifications) : isSet(object.push_notifications) ? globalThis.Boolean(object.push_notifications) : false,
      extensions: globalThis.Array.isArray(object?.extensions) ? object.extensions.map((e) => AgentExtension.fromJSON(e)) : []
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.streaming !== false) {
      obj.streaming = message.streaming;
    }
    if (message.pushNotifications !== false) {
      obj.pushNotifications = message.pushNotifications;
    }
    if (message.extensions?.length) {
      obj.extensions = message.extensions.map((e) => AgentExtension.toJSON(e));
    }
    return obj;
  }
};
var AgentExtension = {
  fromJSON(object) {
    return {
      uri: isSet(object.uri) ? globalThis.String(object.uri) : "",
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      required: isSet(object.required) ? globalThis.Boolean(object.required) : false,
      params: isObject(object.params) ? object.params : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.uri !== "") {
      obj.uri = message.uri;
    }
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.required !== false) {
      obj.required = message.required;
    }
    if (message.params !== void 0) {
      obj.params = message.params;
    }
    return obj;
  }
};
var AgentSkill = {
  fromJSON(object) {
    return {
      id: isSet(object.id) ? globalThis.String(object.id) : "",
      name: isSet(object.name) ? globalThis.String(object.name) : "",
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      tags: globalThis.Array.isArray(object?.tags) ? object.tags.map((e) => globalThis.String(e)) : [],
      examples: globalThis.Array.isArray(object?.examples) ? object.examples.map((e) => globalThis.String(e)) : [],
      inputModes: globalThis.Array.isArray(object?.inputModes) ? object.inputModes.map((e) => globalThis.String(e)) : globalThis.Array.isArray(object?.input_modes) ? object.input_modes.map((e) => globalThis.String(e)) : [],
      outputModes: globalThis.Array.isArray(object?.outputModes) ? object.outputModes.map((e) => globalThis.String(e)) : globalThis.Array.isArray(object?.output_modes) ? object.output_modes.map((e) => globalThis.String(e)) : [],
      security: globalThis.Array.isArray(object?.security) ? object.security.map((e) => Security.fromJSON(e)) : []
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.id !== "") {
      obj.id = message.id;
    }
    if (message.name !== "") {
      obj.name = message.name;
    }
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.tags?.length) {
      obj.tags = message.tags;
    }
    if (message.examples?.length) {
      obj.examples = message.examples;
    }
    if (message.inputModes?.length) {
      obj.inputModes = message.inputModes;
    }
    if (message.outputModes?.length) {
      obj.outputModes = message.outputModes;
    }
    if (message.security?.length) {
      obj.security = message.security.map((e) => Security.toJSON(e));
    }
    return obj;
  }
};
var AgentCardSignature = {
  fromJSON(object) {
    return {
      protected: isSet(object.protected) ? globalThis.String(object.protected) : "",
      signature: isSet(object.signature) ? globalThis.String(object.signature) : "",
      header: isObject(object.header) ? object.header : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.protected !== "") {
      obj.protected = message.protected;
    }
    if (message.signature !== "") {
      obj.signature = message.signature;
    }
    if (message.header !== void 0) {
      obj.header = message.header;
    }
    return obj;
  }
};
var TaskPushNotificationConfig = {
  fromJSON(object) {
    return {
      name: isSet(object.name) ? globalThis.String(object.name) : "",
      pushNotificationConfig: isSet(object.pushNotificationConfig) ? PushNotificationConfig.fromJSON(object.pushNotificationConfig) : isSet(object.push_notification_config) ? PushNotificationConfig.fromJSON(object.push_notification_config) : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.name !== "") {
      obj.name = message.name;
    }
    if (message.pushNotificationConfig !== void 0) {
      obj.pushNotificationConfig = PushNotificationConfig.toJSON(message.pushNotificationConfig);
    }
    return obj;
  }
};
var StringList = {
  fromJSON(object) {
    return { list: globalThis.Array.isArray(object?.list) ? object.list.map((e) => globalThis.String(e)) : [] };
  },
  toJSON(message) {
    const obj = {};
    if (message.list?.length) {
      obj.list = message.list;
    }
    return obj;
  }
};
var Security = {
  fromJSON(object) {
    return {
      schemes: isObject(object.schemes) ? globalThis.Object.entries(object.schemes).reduce(
        (acc, [key, value]) => {
          acc[key] = StringList.fromJSON(value);
          return acc;
        },
        {}
      ) : {}
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.schemes) {
      const entries = globalThis.Object.entries(message.schemes);
      if (entries.length > 0) {
        obj.schemes = {};
        entries.forEach(([k, v]) => {
          obj.schemes[k] = StringList.toJSON(v);
        });
      }
    }
    return obj;
  }
};
var SecurityScheme = {
  fromJSON(object) {
    return {
      scheme: isSet(object.apiKeySecurityScheme) ? { $case: "apiKeySecurityScheme", value: APIKeySecurityScheme.fromJSON(object.apiKeySecurityScheme) } : isSet(object.api_key_security_scheme) ? { $case: "apiKeySecurityScheme", value: APIKeySecurityScheme.fromJSON(object.api_key_security_scheme) } : isSet(object.httpAuthSecurityScheme) ? { $case: "httpAuthSecurityScheme", value: HTTPAuthSecurityScheme.fromJSON(object.httpAuthSecurityScheme) } : isSet(object.http_auth_security_scheme) ? { $case: "httpAuthSecurityScheme", value: HTTPAuthSecurityScheme.fromJSON(object.http_auth_security_scheme) } : isSet(object.oauth2SecurityScheme) ? { $case: "oauth2SecurityScheme", value: OAuth2SecurityScheme.fromJSON(object.oauth2SecurityScheme) } : isSet(object.oauth2_security_scheme) ? { $case: "oauth2SecurityScheme", value: OAuth2SecurityScheme.fromJSON(object.oauth2_security_scheme) } : isSet(object.openIdConnectSecurityScheme) ? {
        $case: "openIdConnectSecurityScheme",
        value: OpenIdConnectSecurityScheme.fromJSON(object.openIdConnectSecurityScheme)
      } : isSet(object.open_id_connect_security_scheme) ? {
        $case: "openIdConnectSecurityScheme",
        value: OpenIdConnectSecurityScheme.fromJSON(object.open_id_connect_security_scheme)
      } : isSet(object.mtlsSecurityScheme) ? { $case: "mtlsSecurityScheme", value: MutualTlsSecurityScheme.fromJSON(object.mtlsSecurityScheme) } : isSet(object.mtls_security_scheme) ? { $case: "mtlsSecurityScheme", value: MutualTlsSecurityScheme.fromJSON(object.mtls_security_scheme) } : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.scheme?.$case === "apiKeySecurityScheme") {
      obj.apiKeySecurityScheme = APIKeySecurityScheme.toJSON(message.scheme.value);
    } else if (message.scheme?.$case === "httpAuthSecurityScheme") {
      obj.httpAuthSecurityScheme = HTTPAuthSecurityScheme.toJSON(message.scheme.value);
    } else if (message.scheme?.$case === "oauth2SecurityScheme") {
      obj.oauth2SecurityScheme = OAuth2SecurityScheme.toJSON(message.scheme.value);
    } else if (message.scheme?.$case === "openIdConnectSecurityScheme") {
      obj.openIdConnectSecurityScheme = OpenIdConnectSecurityScheme.toJSON(message.scheme.value);
    } else if (message.scheme?.$case === "mtlsSecurityScheme") {
      obj.mtlsSecurityScheme = MutualTlsSecurityScheme.toJSON(message.scheme.value);
    }
    return obj;
  }
};
var APIKeySecurityScheme = {
  fromJSON(object) {
    return {
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      location: isSet(object.location) ? globalThis.String(object.location) : "",
      name: isSet(object.name) ? globalThis.String(object.name) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.location !== "") {
      obj.location = message.location;
    }
    if (message.name !== "") {
      obj.name = message.name;
    }
    return obj;
  }
};
var HTTPAuthSecurityScheme = {
  fromJSON(object) {
    return {
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      scheme: isSet(object.scheme) ? globalThis.String(object.scheme) : "",
      bearerFormat: isSet(object.bearerFormat) ? globalThis.String(object.bearerFormat) : isSet(object.bearer_format) ? globalThis.String(object.bearer_format) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.scheme !== "") {
      obj.scheme = message.scheme;
    }
    if (message.bearerFormat !== "") {
      obj.bearerFormat = message.bearerFormat;
    }
    return obj;
  }
};
var OAuth2SecurityScheme = {
  fromJSON(object) {
    return {
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      flows: isSet(object.flows) ? OAuthFlows.fromJSON(object.flows) : void 0,
      oauth2MetadataUrl: isSet(object.oauth2MetadataUrl) ? globalThis.String(object.oauth2MetadataUrl) : isSet(object.oauth2_metadata_url) ? globalThis.String(object.oauth2_metadata_url) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.flows !== void 0) {
      obj.flows = OAuthFlows.toJSON(message.flows);
    }
    if (message.oauth2MetadataUrl !== "") {
      obj.oauth2MetadataUrl = message.oauth2MetadataUrl;
    }
    return obj;
  }
};
var OpenIdConnectSecurityScheme = {
  fromJSON(object) {
    return {
      description: isSet(object.description) ? globalThis.String(object.description) : "",
      openIdConnectUrl: isSet(object.openIdConnectUrl) ? globalThis.String(object.openIdConnectUrl) : isSet(object.open_id_connect_url) ? globalThis.String(object.open_id_connect_url) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.description !== "") {
      obj.description = message.description;
    }
    if (message.openIdConnectUrl !== "") {
      obj.openIdConnectUrl = message.openIdConnectUrl;
    }
    return obj;
  }
};
var MutualTlsSecurityScheme = {
  fromJSON(object) {
    return { description: isSet(object.description) ? globalThis.String(object.description) : "" };
  },
  toJSON(message) {
    const obj = {};
    if (message.description !== "") {
      obj.description = message.description;
    }
    return obj;
  }
};
var OAuthFlows = {
  fromJSON(object) {
    return {
      flow: isSet(object.authorizationCode) ? { $case: "authorizationCode", value: AuthorizationCodeOAuthFlow.fromJSON(object.authorizationCode) } : isSet(object.authorization_code) ? { $case: "authorizationCode", value: AuthorizationCodeOAuthFlow.fromJSON(object.authorization_code) } : isSet(object.clientCredentials) ? { $case: "clientCredentials", value: ClientCredentialsOAuthFlow.fromJSON(object.clientCredentials) } : isSet(object.client_credentials) ? { $case: "clientCredentials", value: ClientCredentialsOAuthFlow.fromJSON(object.client_credentials) } : isSet(object.implicit) ? { $case: "implicit", value: ImplicitOAuthFlow.fromJSON(object.implicit) } : isSet(object.password) ? { $case: "password", value: PasswordOAuthFlow.fromJSON(object.password) } : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.flow?.$case === "authorizationCode") {
      obj.authorizationCode = AuthorizationCodeOAuthFlow.toJSON(message.flow.value);
    } else if (message.flow?.$case === "clientCredentials") {
      obj.clientCredentials = ClientCredentialsOAuthFlow.toJSON(message.flow.value);
    } else if (message.flow?.$case === "implicit") {
      obj.implicit = ImplicitOAuthFlow.toJSON(message.flow.value);
    } else if (message.flow?.$case === "password") {
      obj.password = PasswordOAuthFlow.toJSON(message.flow.value);
    }
    return obj;
  }
};
var AuthorizationCodeOAuthFlow = {
  fromJSON(object) {
    return {
      authorizationUrl: isSet(object.authorizationUrl) ? globalThis.String(object.authorizationUrl) : isSet(object.authorization_url) ? globalThis.String(object.authorization_url) : "",
      tokenUrl: isSet(object.tokenUrl) ? globalThis.String(object.tokenUrl) : isSet(object.token_url) ? globalThis.String(object.token_url) : "",
      refreshUrl: isSet(object.refreshUrl) ? globalThis.String(object.refreshUrl) : isSet(object.refresh_url) ? globalThis.String(object.refresh_url) : "",
      scopes: isObject(object.scopes) ? globalThis.Object.entries(object.scopes).reduce(
        (acc, [key, value]) => {
          acc[key] = globalThis.String(value);
          return acc;
        },
        {}
      ) : {}
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.authorizationUrl !== "") {
      obj.authorizationUrl = message.authorizationUrl;
    }
    if (message.tokenUrl !== "") {
      obj.tokenUrl = message.tokenUrl;
    }
    if (message.refreshUrl !== "") {
      obj.refreshUrl = message.refreshUrl;
    }
    if (message.scopes) {
      const entries = globalThis.Object.entries(message.scopes);
      if (entries.length > 0) {
        obj.scopes = {};
        entries.forEach(([k, v]) => {
          obj.scopes[k] = v;
        });
      }
    }
    return obj;
  }
};
var ClientCredentialsOAuthFlow = {
  fromJSON(object) {
    return {
      tokenUrl: isSet(object.tokenUrl) ? globalThis.String(object.tokenUrl) : isSet(object.token_url) ? globalThis.String(object.token_url) : "",
      refreshUrl: isSet(object.refreshUrl) ? globalThis.String(object.refreshUrl) : isSet(object.refresh_url) ? globalThis.String(object.refresh_url) : "",
      scopes: isObject(object.scopes) ? globalThis.Object.entries(object.scopes).reduce(
        (acc, [key, value]) => {
          acc[key] = globalThis.String(value);
          return acc;
        },
        {}
      ) : {}
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.tokenUrl !== "") {
      obj.tokenUrl = message.tokenUrl;
    }
    if (message.refreshUrl !== "") {
      obj.refreshUrl = message.refreshUrl;
    }
    if (message.scopes) {
      const entries = globalThis.Object.entries(message.scopes);
      if (entries.length > 0) {
        obj.scopes = {};
        entries.forEach(([k, v]) => {
          obj.scopes[k] = v;
        });
      }
    }
    return obj;
  }
};
var ImplicitOAuthFlow = {
  fromJSON(object) {
    return {
      authorizationUrl: isSet(object.authorizationUrl) ? globalThis.String(object.authorizationUrl) : isSet(object.authorization_url) ? globalThis.String(object.authorization_url) : "",
      refreshUrl: isSet(object.refreshUrl) ? globalThis.String(object.refreshUrl) : isSet(object.refresh_url) ? globalThis.String(object.refresh_url) : "",
      scopes: isObject(object.scopes) ? globalThis.Object.entries(object.scopes).reduce(
        (acc, [key, value]) => {
          acc[key] = globalThis.String(value);
          return acc;
        },
        {}
      ) : {}
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.authorizationUrl !== "") {
      obj.authorizationUrl = message.authorizationUrl;
    }
    if (message.refreshUrl !== "") {
      obj.refreshUrl = message.refreshUrl;
    }
    if (message.scopes) {
      const entries = globalThis.Object.entries(message.scopes);
      if (entries.length > 0) {
        obj.scopes = {};
        entries.forEach(([k, v]) => {
          obj.scopes[k] = v;
        });
      }
    }
    return obj;
  }
};
var PasswordOAuthFlow = {
  fromJSON(object) {
    return {
      tokenUrl: isSet(object.tokenUrl) ? globalThis.String(object.tokenUrl) : isSet(object.token_url) ? globalThis.String(object.token_url) : "",
      refreshUrl: isSet(object.refreshUrl) ? globalThis.String(object.refreshUrl) : isSet(object.refresh_url) ? globalThis.String(object.refresh_url) : "",
      scopes: isObject(object.scopes) ? globalThis.Object.entries(object.scopes).reduce(
        (acc, [key, value]) => {
          acc[key] = globalThis.String(value);
          return acc;
        },
        {}
      ) : {}
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.tokenUrl !== "") {
      obj.tokenUrl = message.tokenUrl;
    }
    if (message.refreshUrl !== "") {
      obj.refreshUrl = message.refreshUrl;
    }
    if (message.scopes) {
      const entries = globalThis.Object.entries(message.scopes);
      if (entries.length > 0) {
        obj.scopes = {};
        entries.forEach(([k, v]) => {
          obj.scopes[k] = v;
        });
      }
    }
    return obj;
  }
};
var SendMessageRequest = {
  fromJSON(object) {
    return {
      request: isSet(object.message) ? Message.fromJSON(object.message) : isSet(object.request) ? Message.fromJSON(object.request) : void 0,
      configuration: isSet(object.configuration) ? SendMessageConfiguration.fromJSON(object.configuration) : void 0,
      metadata: isObject(object.metadata) ? object.metadata : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.request !== void 0) {
      obj.message = Message.toJSON(message.request);
    }
    if (message.configuration !== void 0) {
      obj.configuration = SendMessageConfiguration.toJSON(message.configuration);
    }
    if (message.metadata !== void 0) {
      obj.metadata = message.metadata;
    }
    return obj;
  }
};
var SendMessageResponse = {
  fromJSON(object) {
    return {
      payload: isSet(object.task) ? { $case: "task", value: Task.fromJSON(object.task) } : isSet(object.message) ? { $case: "msg", value: Message.fromJSON(object.message) } : isSet(object.msg) ? { $case: "msg", value: Message.fromJSON(object.msg) } : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.payload?.$case === "task") {
      obj.task = Task.toJSON(message.payload.value);
    } else if (message.payload?.$case === "msg") {
      obj.message = Message.toJSON(message.payload.value);
    }
    return obj;
  }
};
var StreamResponse = {
  fromJSON(object) {
    return {
      payload: isSet(object.task) ? { $case: "task", value: Task.fromJSON(object.task) } : isSet(object.message) ? { $case: "msg", value: Message.fromJSON(object.message) } : isSet(object.msg) ? { $case: "msg", value: Message.fromJSON(object.msg) } : isSet(object.statusUpdate) ? { $case: "statusUpdate", value: TaskStatusUpdateEvent.fromJSON(object.statusUpdate) } : isSet(object.status_update) ? { $case: "statusUpdate", value: TaskStatusUpdateEvent.fromJSON(object.status_update) } : isSet(object.artifactUpdate) ? { $case: "artifactUpdate", value: TaskArtifactUpdateEvent.fromJSON(object.artifactUpdate) } : isSet(object.artifact_update) ? { $case: "artifactUpdate", value: TaskArtifactUpdateEvent.fromJSON(object.artifact_update) } : void 0
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.payload?.$case === "task") {
      obj.task = Task.toJSON(message.payload.value);
    } else if (message.payload?.$case === "msg") {
      obj.message = Message.toJSON(message.payload.value);
    } else if (message.payload?.$case === "statusUpdate") {
      obj.statusUpdate = TaskStatusUpdateEvent.toJSON(message.payload.value);
    } else if (message.payload?.$case === "artifactUpdate") {
      obj.artifactUpdate = TaskArtifactUpdateEvent.toJSON(message.payload.value);
    }
    return obj;
  }
};
var ListTaskPushNotificationConfigResponse = {
  fromJSON(object) {
    return {
      configs: globalThis.Array.isArray(object?.configs) ? object.configs.map((e) => TaskPushNotificationConfig.fromJSON(e)) : [],
      nextPageToken: isSet(object.nextPageToken) ? globalThis.String(object.nextPageToken) : isSet(object.next_page_token) ? globalThis.String(object.next_page_token) : ""
    };
  },
  toJSON(message) {
    const obj = {};
    if (message.configs?.length) {
      obj.configs = message.configs.map((e) => TaskPushNotificationConfig.toJSON(e));
    }
    if (message.nextPageToken !== "") {
      obj.nextPageToken = message.nextPageToken;
    }
    return obj;
  }
};
function bytesFromBase64(b64) {
  return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
}
function base64FromBytes(arr) {
  return globalThis.Buffer.from(arr).toString("base64");
}
function isObject(value) {
  return typeof value === "object" && value !== null;
}
function isSet(value) {
  return value !== null && value !== void 0;
}

// src/server/error.ts
var A2AError = class _A2AError extends Error {
  code;
  data;
  taskId;
  // Optional task ID context
  constructor(code, message, data, taskId) {
    super(message);
    this.name = "A2AError";
    this.code = code;
    this.data = data;
    this.taskId = taskId;
  }
  /**
   * Formats the error into a standard JSON-RPC error object structure.
   */
  toJSONRPCError() {
    const errorObject = {
      code: this.code,
      message: this.message
    };
    if (this.data !== void 0) {
      errorObject.data = this.data;
    }
    return errorObject;
  }
  // Static factory methods for common errors
  static parseError(message, data) {
    return new _A2AError(-32700, message, data);
  }
  static invalidRequest(message, data) {
    return new _A2AError(-32600, message, data);
  }
  static methodNotFound(method) {
    return new _A2AError(-32601, `Method not found: ${method}`);
  }
  static invalidParams(message, data) {
    return new _A2AError(-32602, message, data);
  }
  static internalError(message, data) {
    return new _A2AError(-32603, message, data);
  }
  static taskNotFound(taskId) {
    return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
  }
  static taskNotCancelable(taskId) {
    return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
  }
  static pushNotificationNotSupported() {
    return new _A2AError(-32003, "Push Notification is not supported");
  }
  static unsupportedOperation(operation) {
    return new _A2AError(-32004, `Unsupported operation: ${operation}`);
  }
  static authenticatedExtendedCardNotConfigured() {
    return new _A2AError(-32007, `Extended card not configured.`);
  }
};

// src/types/converters/id_decoding.ts
var CONFIG_REGEX = /^tasks\/([^/]+)\/pushNotificationConfigs\/([^/]+)$/;
var TASK_ONLY_REGEX = /^tasks\/([^/]+)(?:\/|$)/;
var extractTaskId = (name) => {
  const match = name.match(TASK_ONLY_REGEX);
  if (!match) {
    throw A2AError.invalidParams(`Invalid or missing task ID in: "${name}"`);
  }
  return match[1];
};
var generateTaskName = (taskId) => {
  return `tasks/${taskId}`;
};
var extractTaskAndPushNotificationConfigId = (name) => {
  const match = name.match(CONFIG_REGEX);
  if (!match) {
    throw A2AError.invalidParams(`Invalid or missing config ID in: "${name}"`);
  }
  return { taskId: match[1], configId: match[2] };
};
var generatePushNotificationConfigName = (taskId, configId) => {
  return `tasks/${taskId}/pushNotificationConfigs/${configId}`;
};

// src/types/converters/from_proto.ts
var FromProto = class _FromProto {
  static taskQueryParams(request) {
    return {
      id: extractTaskId(request.name),
      historyLength: request.historyLength
    };
  }
  static taskIdParams(request) {
    return {
      id: extractTaskId(request.name)
    };
  }
  static getTaskPushNotificationConfigParams(request) {
    const { taskId, configId } = extractTaskAndPushNotificationConfigId(request.name);
    return {
      id: taskId,
      pushNotificationConfigId: configId
    };
  }
  static listTaskPushNotificationConfigParams(request) {
    return {
      id: extractTaskId(request.parent)
    };
  }
  static createTaskPushNotificationConfig(request) {
    if (!request.config?.pushNotificationConfig) {
      throw A2AError.invalidParams(
        "Request must include a `config` object with a `pushNotificationConfig`"
      );
    }
    return {
      taskId: extractTaskId(request.parent),
      pushNotificationConfig: _FromProto.pushNotificationConfig(
        request.config.pushNotificationConfig
      )
    };
  }
  static deleteTaskPushNotificationConfigParams(request) {
    const { taskId, configId } = extractTaskAndPushNotificationConfigId(request.name);
    return {
      id: taskId,
      pushNotificationConfigId: configId
    };
  }
  static message(message) {
    if (!message) {
      return void 0;
    }
    return {
      kind: "message",
      messageId: message.messageId,
      parts: message.content.map((p) => _FromProto.part(p)),
      contextId: message.contextId || void 0,
      taskId: message.taskId || void 0,
      role: _FromProto.role(message.role),
      metadata: message.metadata,
      extensions: message.extensions
    };
  }
  static role(role) {
    switch (role) {
      case 2 /* ROLE_AGENT */:
        return "agent";
      case 1 /* ROLE_USER */:
        return "user";
      default:
        throw A2AError.invalidParams(`Invalid role: ${role}`);
    }
  }
  static messageSendConfiguration(configuration) {
    if (!configuration) {
      return void 0;
    }
    return {
      blocking: configuration.blocking,
      acceptedOutputModes: configuration.acceptedOutputModes,
      pushNotificationConfig: _FromProto.pushNotificationConfig(configuration.pushNotification)
    };
  }
  static pushNotificationConfig(config) {
    if (!config) {
      return void 0;
    }
    return {
      id: config.id,
      url: config.url,
      token: config.token || void 0,
      authentication: _FromProto.pushNotificationAuthenticationInfo(config.authentication)
    };
  }
  static pushNotificationAuthenticationInfo(authInfo) {
    if (!authInfo) {
      return void 0;
    }
    return {
      schemes: authInfo.schemes,
      credentials: authInfo.credentials
    };
  }
  static part(part) {
    if (part.part?.$case === "text") {
      return {
        kind: "text",
        text: part.part.value
      };
    }
    if (part.part?.$case === "file") {
      const filePart = part.part.value;
      if (filePart.file?.$case === "fileWithUri") {
        return {
          kind: "file",
          file: {
            uri: filePart.file.value,
            mimeType: filePart.mimeType
          }
        };
      } else if (filePart.file?.$case === "fileWithBytes") {
        return {
          kind: "file",
          file: {
            bytes: filePart.file.value.toString("base64"),
            mimeType: filePart.mimeType
          }
        };
      }
      throw A2AError.invalidParams("Invalid file part type");
    }
    if (part.part?.$case === "data") {
      return {
        kind: "data",
        data: part.part.value.data
      };
    }
    throw A2AError.invalidParams("Invalid part type");
  }
  static messageSendParams(request) {
    return {
      message: _FromProto.message(request.request),
      configuration: _FromProto.messageSendConfiguration(request.configuration),
      metadata: request.metadata
    };
  }
  static sendMessageResult(response) {
    if (response.payload?.$case === "task") {
      return _FromProto.task(response.payload.value);
    } else if (response.payload?.$case === "msg") {
      return _FromProto.message(response.payload.value);
    }
    throw A2AError.invalidParams("Invalid SendMessageResponse: missing result");
  }
  static task(task) {
    return {
      kind: "task",
      id: task.id,
      status: _FromProto.taskStatus(task.status),
      contextId: task.contextId,
      artifacts: task.artifacts?.map((a) => _FromProto.artifact(a)),
      history: task.history?.map((h) => _FromProto.message(h)),
      metadata: task.metadata
    };
  }
  static taskStatus(status) {
    return {
      message: _FromProto.message(status.update),
      state: _FromProto.taskState(status.state),
      timestamp: status.timestamp
    };
  }
  static taskState(state) {
    switch (state) {
      case 1 /* TASK_STATE_SUBMITTED */:
        return "submitted";
      case 2 /* TASK_STATE_WORKING */:
        return "working";
      case 6 /* TASK_STATE_INPUT_REQUIRED */:
        return "input-required";
      case 3 /* TASK_STATE_COMPLETED */:
        return "completed";
      case 5 /* TASK_STATE_CANCELLED */:
        return "canceled";
      case 4 /* TASK_STATE_FAILED */:
        return "failed";
      case 7 /* TASK_STATE_REJECTED */:
        return "rejected";
      case 8 /* TASK_STATE_AUTH_REQUIRED */:
        return "auth-required";
      case 0 /* TASK_STATE_UNSPECIFIED */:
        return "unknown";
      default:
        throw A2AError.invalidParams(`Invalid task state: ${state}`);
    }
  }
  static artifact(artifact) {
    return {
      artifactId: artifact.artifactId,
      name: artifact.name || void 0,
      description: artifact.description || void 0,
      parts: artifact.parts.map((p) => _FromProto.part(p)),
      metadata: artifact.metadata
    };
  }
  static taskPushNotificationConfig(request) {
    return {
      taskId: extractTaskId(request.name),
      pushNotificationConfig: _FromProto.pushNotificationConfig(request.pushNotificationConfig)
    };
  }
  static listTaskPushNotificationConfig(request) {
    return request.configs.map((c) => _FromProto.taskPushNotificationConfig(c));
  }
  static agentCard(agentCard) {
    return {
      additionalInterfaces: agentCard.additionalInterfaces?.map((i) => _FromProto.agentInterface(i)),
      capabilities: agentCard.capabilities ? _FromProto.agentCapabilities(agentCard.capabilities) : {},
      defaultInputModes: agentCard.defaultInputModes,
      defaultOutputModes: agentCard.defaultOutputModes,
      description: agentCard.description,
      documentationUrl: agentCard.documentationUrl || void 0,
      name: agentCard.name,
      preferredTransport: agentCard.preferredTransport,
      provider: agentCard.provider ? _FromProto.agentProvider(agentCard.provider) : void 0,
      protocolVersion: agentCard.protocolVersion,
      security: agentCard.security?.map((s) => _FromProto.security(s)),
      securitySchemes: agentCard.securitySchemes ? Object.fromEntries(
        Object.entries(agentCard.securitySchemes).map(([key, value]) => [
          key,
          _FromProto.securityScheme(value)
        ])
      ) : {},
      skills: agentCard.skills.map((s) => _FromProto.skills(s)),
      signatures: agentCard.signatures?.map((s) => _FromProto.agentCardSignature(s)),
      supportsAuthenticatedExtendedCard: agentCard.supportsAuthenticatedExtendedCard,
      url: agentCard.url,
      version: agentCard.version
    };
  }
  static agentCapabilities(capabilities) {
    return {
      extensions: capabilities.extensions?.map((e) => _FromProto.agentExtension(e)),
      pushNotifications: capabilities.pushNotifications,
      streaming: capabilities.streaming
    };
  }
  static agentExtension(extension) {
    return {
      uri: extension.uri,
      description: extension.description || void 0,
      required: extension.required,
      params: extension.params
    };
  }
  static agentInterface(intf) {
    return {
      transport: intf.transport,
      url: intf.url
    };
  }
  static agentProvider(provider) {
    return {
      organization: provider.organization,
      url: provider.url
    };
  }
  static security(security) {
    return Object.fromEntries(
      Object.entries(security.schemes)?.map(([key, value]) => [key, value.list])
    );
  }
  static securityScheme(securitySchemes) {
    switch (securitySchemes.scheme?.$case) {
      case "apiKeySecurityScheme":
        return {
          type: "apiKey",
          name: securitySchemes.scheme.value.name,
          in: securitySchemes.scheme.value.location,
          description: securitySchemes.scheme.value.description || void 0
        };
      case "httpAuthSecurityScheme":
        return {
          type: "http",
          scheme: securitySchemes.scheme.value.scheme,
          bearerFormat: securitySchemes.scheme.value.bearerFormat || void 0,
          description: securitySchemes.scheme.value.description || void 0
        };
      case "mtlsSecurityScheme":
        return {
          type: "mutualTLS",
          description: securitySchemes.scheme.value.description || void 0
        };
      case "oauth2SecurityScheme":
        return {
          type: "oauth2",
          description: securitySchemes.scheme.value.description || void 0,
          flows: _FromProto.oauthFlows(securitySchemes.scheme.value.flows),
          oauth2MetadataUrl: securitySchemes.scheme.value.oauth2MetadataUrl || void 0
        };
      case "openIdConnectSecurityScheme":
        return {
          type: "openIdConnect",
          description: securitySchemes.scheme.value.description || void 0,
          openIdConnectUrl: securitySchemes.scheme.value.openIdConnectUrl
        };
      default:
        throw A2AError.internalError(`Unsupported security scheme type`);
    }
  }
  static oauthFlows(flows) {
    switch (flows.flow?.$case) {
      case "implicit":
        return {
          implicit: {
            authorizationUrl: flows.flow.value.authorizationUrl,
            scopes: flows.flow.value.scopes,
            refreshUrl: flows.flow.value.refreshUrl || void 0
          }
        };
      case "password":
        return {
          password: {
            refreshUrl: flows.flow.value.refreshUrl || void 0,
            scopes: flows.flow.value.scopes,
            tokenUrl: flows.flow.value.tokenUrl
          }
        };
      case "authorizationCode":
        return {
          authorizationCode: {
            refreshUrl: flows.flow.value.refreshUrl || void 0,
            authorizationUrl: flows.flow.value.authorizationUrl,
            scopes: flows.flow.value.scopes,
            tokenUrl: flows.flow.value.tokenUrl
          }
        };
      case "clientCredentials":
        return {
          clientCredentials: {
            refreshUrl: flows.flow.value.refreshUrl || void 0,
            scopes: flows.flow.value.scopes,
            tokenUrl: flows.flow.value.tokenUrl
          }
        };
      default:
        throw A2AError.internalError(`Unsupported OAuth flows`);
    }
  }
  static skills(skill) {
    return {
      id: skill.id,
      name: skill.name,
      description: skill.description,
      tags: skill.tags,
      examples: skill.examples,
      inputModes: skill.inputModes,
      outputModes: skill.outputModes,
      security: skill.security?.map((s) => _FromProto.security(s))
    };
  }
  static agentCardSignature(signatures) {
    return {
      protected: signatures.protected,
      signature: signatures.signature,
      header: signatures.header
    };
  }
  static taskStatusUpdateEvent(event) {
    return {
      kind: "status-update",
      taskId: event.taskId,
      status: _FromProto.taskStatus(event.status),
      contextId: event.contextId,
      metadata: event.metadata,
      final: event.final
    };
  }
  static taskArtifactUpdateEvent(event) {
    return {
      kind: "artifact-update",
      taskId: event.taskId,
      artifact: _FromProto.artifact(event.artifact),
      contextId: event.contextId,
      metadata: event.metadata,
      lastChunk: event.lastChunk
    };
  }
  static messageStreamResult(event) {
    switch (event.payload?.$case) {
      case "msg":
        return _FromProto.message(event.payload.value);
      case "task":
        return _FromProto.task(event.payload.value);
      case "statusUpdate":
        return _FromProto.taskStatusUpdateEvent(event.payload.value);
      case "artifactUpdate":
        return _FromProto.taskArtifactUpdateEvent(event.payload.value);
      default:
        throw A2AError.internalError("Invalid event type in StreamResponse");
    }
  }
};

// src/client/card-resolver.ts
var DefaultAgentCardResolver = class {
  constructor(options) {
    this.options = options;
  }
  /**
   * Fetches the agent card based on provided base URL and path.
   * Path is selected in the following order:
   * 1) path parameter
   * 2) path from options
   * 3) .well-known/agent-card.json
   */
  async resolve(baseUrl, path) {
    const agentCardUrl = new URL(path ?? this.options?.path ?? AGENT_CARD_PATH, baseUrl);
    const response = await this.fetchImpl(agentCardUrl);
    if (!response.ok) {
      throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status}`);
    }
    const rawCard = await response.json();
    return this.normalizeAgentCard(rawCard);
  }
  fetchImpl(...args) {
    if (this.options?.fetchImpl) {
      return this.options.fetchImpl(...args);
    }
    return fetch(...args);
  }
  /*
   * In the v0.3.0 specification, there was a structural drift between the JSON Schema data model
   * and the Protobuf-based data model for AgentCards.
   * The JSON Schema format uses a `"type"` discriminator (e.g., `{"type": "openIdConnect"}`),
   * while the Protobuf JSON representation uses the `oneof` field name as the discriminator
   * (e.g., `{"openIdConnectSecurityScheme": {...}}`).
   *
   * The A2A SDK internal logic expects the JSON Schema-based format. This fallback detection
   * allows us to parse cards served by endpoints returning the Protobuf JSON structure by
   * identifying the lack of the "type" field in security schemes or the presence of the
   * "schemes" wrapper in security entries, and normalizing it before use.
   */
  normalizeAgentCard(card) {
    if (this.isProtoAgentCard(card)) {
      const parsedProto = AgentCard.fromJSON(card);
      return FromProto.agentCard(parsedProto);
    }
    return card;
  }
  isProtoAgentCard(card) {
    if (!card || typeof card !== "object") return false;
    const c = card;
    if (this.hasProtoSecurity(c.security)) return true;
    if (this.hasProtoSecuritySchemes(c.securitySchemes)) return true;
    if (Array.isArray(c.skills)) {
      return c.skills.some(
        (skill) => skill && typeof skill === "object" && this.hasProtoSecurity(skill.security)
      );
    }
    return false;
  }
  hasProtoSecurity(securityArray) {
    if (Array.isArray(securityArray) && securityArray.length > 0) {
      const first = securityArray[0];
      return first && typeof first === "object" && "schemes" in first;
    }
    return false;
  }
  hasProtoSecuritySchemes(securitySchemes) {
    if (securitySchemes && typeof securitySchemes === "object") {
      const schemes = Object.values(securitySchemes);
      if (schemes.length > 0) {
        const first = schemes[0];
        return first && typeof first === "object" && !("type" in first);
      }
    }
    return false;
  }
};
var AgentCardResolver = {
  default: new DefaultAgentCardResolver()
};

// src/client/multitransport-client.ts
var Client = class {
  constructor(transport, agentCard, config) {
    this.transport = transport;
    this.agentCard = agentCard;
    this.config = config;
  }
  /**
   * If the current agent card supports the extended feature, it will try to fetch the extended agent card from the server,
   * Otherwise it will return the current agent card value.
   */
  async getAgentCard(options) {
    if (this.agentCard.supportsAuthenticatedExtendedCard) {
      this.agentCard = await this.executeWithInterceptors(
        { method: "getAgentCard" },
        options,
        (_, options2) => this.transport.getExtendedAgentCard(options2)
      );
    }
    return this.agentCard;
  }
  /**
   * Sends a message to an agent to initiate a new interaction or to continue an existing one.
   * Uses blocking mode by default.
   */
  sendMessage(params, options) {
    params = this.applyClientConfig({
      params,
      blocking: !(this.config?.polling ?? false)
    });
    return this.executeWithInterceptors(
      { method: "sendMessage", value: params },
      options,
      this.transport.sendMessage.bind(this.transport)
    );
  }
  /**
   * Sends a message to an agent to initiate/continue a task AND subscribes the client to real-time updates for that task.
   * Performs fallback to non-streaming if not supported by the agent.
   */
  async *sendMessageStream(params, options) {
    const method = "sendMessageStream";
    params = this.applyClientConfig({ params, blocking: true });
    const beforeArgs = {
      input: { method, value: params },
      agentCard: this.agentCard,
      options
    };
    const beforeResult = await this.interceptBefore(beforeArgs);
    if (beforeResult) {
      const earlyReturn = beforeResult.earlyReturn.value;
      const afterArgs = {
        result: { method, value: earlyReturn },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs, beforeResult.executed);
      yield afterArgs.result.value;
      return;
    }
    if (!this.agentCard.capabilities.streaming) {
      const result = await this.transport.sendMessage(beforeArgs.input.value, beforeArgs.options);
      const afterArgs = {
        result: { method, value: result },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs);
      yield afterArgs.result.value;
      return;
    }
    for await (const event of this.transport.sendMessageStream(
      beforeArgs.input.value,
      beforeArgs.options
    )) {
      const afterArgs = {
        result: { method, value: event },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs);
      yield afterArgs.result.value;
      if (afterArgs.earlyReturn) {
        return;
      }
    }
  }
  /**
   * Sets or updates the push notification configuration for a specified task.
   * Requires the server to have AgentCard.capabilities.pushNotifications: true.
   */
  setTaskPushNotificationConfig(params, options) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw new PushNotificationNotSupportedError();
    }
    return this.executeWithInterceptors(
      { method: "setTaskPushNotificationConfig", value: params },
      options,
      this.transport.setTaskPushNotificationConfig.bind(this.transport)
    );
  }
  /**
   * Retrieves the current push notification configuration for a specified task.
   * Requires the server to have AgentCard.capabilities.pushNotifications: true.
   */
  getTaskPushNotificationConfig(params, options) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw new PushNotificationNotSupportedError();
    }
    return this.executeWithInterceptors(
      { method: "getTaskPushNotificationConfig", value: params },
      options,
      this.transport.getTaskPushNotificationConfig.bind(this.transport)
    );
  }
  /**
   * Retrieves the associated push notification configurations for a specified task.
   * Requires the server to have AgentCard.capabilities.pushNotifications: true.
   */
  listTaskPushNotificationConfig(params, options) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw new PushNotificationNotSupportedError();
    }
    return this.executeWithInterceptors(
      { method: "listTaskPushNotificationConfig", value: params },
      options,
      this.transport.listTaskPushNotificationConfig.bind(this.transport)
    );
  }
  /**
   * Deletes an associated push notification configuration for a task.
   */
  deleteTaskPushNotificationConfig(params, options) {
    return this.executeWithInterceptors(
      { method: "deleteTaskPushNotificationConfig", value: params },
      options,
      this.transport.deleteTaskPushNotificationConfig.bind(this.transport)
    );
  }
  /**
   * Retrieves the current state (including status, artifacts, and optionally history) of a previously initiated task.
   */
  getTask(params, options) {
    return this.executeWithInterceptors(
      { method: "getTask", value: params },
      options,
      this.transport.getTask.bind(this.transport)
    );
  }
  /**
   * Requests the cancellation of an ongoing task. The server will attempt to cancel the task,
   * but success is not guaranteed (e.g., the task might have already completed or failed, or cancellation might not be supported at its current stage).
   */
  cancelTask(params, options) {
    return this.executeWithInterceptors(
      { method: "cancelTask", value: params },
      options,
      this.transport.cancelTask.bind(this.transport)
    );
  }
  /**
   * Allows a client to reconnect to an updates stream for an ongoing task after a previous connection was interrupted.
   */
  async *resubscribeTask(params, options) {
    const method = "resubscribeTask";
    const beforeArgs = {
      input: { method, value: params },
      agentCard: this.agentCard,
      options
    };
    const beforeResult = await this.interceptBefore(beforeArgs);
    if (beforeResult) {
      const earlyReturn = beforeResult.earlyReturn.value;
      const afterArgs = {
        result: { method, value: earlyReturn },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs, beforeResult.executed);
      yield afterArgs.result.value;
      return;
    }
    for await (const event of this.transport.resubscribeTask(
      beforeArgs.input.value,
      beforeArgs.options
    )) {
      const afterArgs = {
        result: { method, value: event },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs);
      yield afterArgs.result.value;
      if (afterArgs.earlyReturn) {
        return;
      }
    }
  }
  applyClientConfig({
    params,
    blocking
  }) {
    const result = { ...params, configuration: params.configuration ?? {} };
    if (!result.configuration.acceptedOutputModes && this.config?.acceptedOutputModes) {
      result.configuration.acceptedOutputModes = this.config.acceptedOutputModes;
    }
    if (!result.configuration.pushNotificationConfig && this.config?.pushNotificationConfig) {
      result.configuration.pushNotificationConfig = this.config.pushNotificationConfig;
    }
    result.configuration.blocking ??= blocking;
    return result;
  }
  async executeWithInterceptors(input, options, transportCall) {
    const beforeArgs = {
      input,
      agentCard: this.agentCard,
      options
    };
    const beforeResult = await this.interceptBefore(beforeArgs);
    if (beforeResult) {
      const afterArgs2 = {
        result: {
          method: input.method,
          value: beforeResult.earlyReturn.value
        },
        agentCard: this.agentCard,
        options: beforeArgs.options
      };
      await this.interceptAfter(afterArgs2, beforeResult.executed);
      return afterArgs2.result.value;
    }
    const result = await transportCall(beforeArgs.input.value, beforeArgs.options);
    const afterArgs = {
      result: { method: input.method, value: result },
      agentCard: this.agentCard,
      options: beforeArgs.options
    };
    await this.interceptAfter(afterArgs);
    return afterArgs.result.value;
  }
  async interceptBefore(args) {
    if (!this.config?.interceptors || this.config.interceptors.length === 0) {
      return;
    }
    const executed = [];
    for (const interceptor of this.config.interceptors) {
      await interceptor.before(args);
      executed.push(interceptor);
      if (args.earlyReturn) {
        return {
          earlyReturn: args.earlyReturn,
          executed
        };
      }
    }
  }
  async interceptAfter(args, interceptors) {
    const reversedInterceptors = [...interceptors ?? this.config?.interceptors ?? []].reverse();
    for (const interceptor of reversedInterceptors) {
      await interceptor.after(args);
      if (args.earlyReturn) {
        return;
      }
    }
  }
};

// src/types/converters/to_proto.ts
var ToProto = class _ToProto {
  static agentCard(agentCard) {
    return {
      protocolVersion: agentCard.protocolVersion,
      name: agentCard.name,
      description: agentCard.description,
      url: agentCard.url,
      preferredTransport: agentCard.preferredTransport ?? "",
      additionalInterfaces: agentCard.additionalInterfaces?.map((i) => _ToProto.agentInterface(i)) ?? [],
      provider: _ToProto.agentProvider(agentCard.provider),
      version: agentCard.version,
      documentationUrl: agentCard.documentationUrl ?? "",
      capabilities: _ToProto.agentCapabilities(agentCard.capabilities),
      securitySchemes: agentCard.securitySchemes ? Object.fromEntries(
        Object.entries(agentCard.securitySchemes).map(([key, value]) => [
          key,
          _ToProto.securityScheme(value)
        ])
      ) : {},
      security: agentCard.security?.map((s) => _ToProto.security(s)) ?? [],
      defaultInputModes: agentCard.defaultInputModes,
      defaultOutputModes: agentCard.defaultOutputModes,
      skills: agentCard.skills.map((s) => _ToProto.agentSkill(s)),
      supportsAuthenticatedExtendedCard: agentCard.supportsAuthenticatedExtendedCard,
      signatures: agentCard.signatures?.map((s) => _ToProto.agentCardSignature(s)) ?? []
    };
  }
  static agentCardSignature(signatures) {
    return {
      protected: signatures.protected,
      signature: signatures.signature,
      header: signatures.header
    };
  }
  static agentSkill(skill) {
    return {
      id: skill.id,
      name: skill.name,
      description: skill.description,
      tags: skill.tags ?? [],
      examples: skill.examples ?? [],
      inputModes: skill.inputModes ?? [],
      outputModes: skill.outputModes ?? [],
      security: skill.security ? skill.security.map((s) => _ToProto.security(s)) : []
    };
  }
  static security(security) {
    return {
      schemes: Object.fromEntries(
        Object.entries(security).map(([key, value]) => {
          return [key, { list: value }];
        })
      )
    };
  }
  static securityScheme(scheme) {
    switch (scheme.type) {
      case "apiKey":
        return {
          scheme: {
            $case: "apiKeySecurityScheme",
            value: {
              name: scheme.name,
              location: scheme.in,
              description: scheme.description ?? ""
            }
          }
        };
      case "http":
        return {
          scheme: {
            $case: "httpAuthSecurityScheme",
            value: {
              description: scheme.description ?? "",
              scheme: scheme.scheme,
              bearerFormat: scheme.bearerFormat ?? ""
            }
          }
        };
      case "mutualTLS":
        return {
          scheme: {
            $case: "mtlsSecurityScheme",
            value: {
              description: scheme.description ?? ""
            }
          }
        };
      case "oauth2":
        return {
          scheme: {
            $case: "oauth2SecurityScheme",
            value: {
              description: scheme.description ?? "",
              flows: _ToProto.oauthFlows(scheme.flows),
              oauth2MetadataUrl: scheme.oauth2MetadataUrl ?? ""
            }
          }
        };
      case "openIdConnect":
        return {
          scheme: {
            $case: "openIdConnectSecurityScheme",
            value: {
              description: scheme.description ?? "",
              openIdConnectUrl: scheme.openIdConnectUrl
            }
          }
        };
      default:
        throw A2AError.internalError(`Unsupported security scheme type`);
    }
  }
  static oauthFlows(flows) {
    if (flows.implicit) {
      return {
        flow: {
          $case: "implicit",
          value: {
            authorizationUrl: flows.implicit.authorizationUrl,
            scopes: flows.implicit.scopes,
            refreshUrl: flows.implicit.refreshUrl ?? ""
          }
        }
      };
    } else if (flows.password) {
      return {
        flow: {
          $case: "password",
          value: {
            tokenUrl: flows.password.tokenUrl,
            scopes: flows.password.scopes,
            refreshUrl: flows.password.refreshUrl ?? ""
          }
        }
      };
    } else if (flows.clientCredentials) {
      return {
        flow: {
          $case: "clientCredentials",
          value: {
            tokenUrl: flows.clientCredentials.tokenUrl,
            scopes: flows.clientCredentials.scopes,
            refreshUrl: flows.clientCredentials.refreshUrl ?? ""
          }
        }
      };
    } else if (flows.authorizationCode) {
      return {
        flow: {
          $case: "authorizationCode",
          value: {
            authorizationUrl: flows.authorizationCode.authorizationUrl,
            tokenUrl: flows.authorizationCode.tokenUrl,
            scopes: flows.authorizationCode.scopes,
            refreshUrl: flows.authorizationCode.refreshUrl ?? ""
          }
        }
      };
    } else {
      throw A2AError.internalError(`Unsupported OAuth flows`);
    }
  }
  static agentInterface(agentInterface) {
    return {
      transport: agentInterface.transport,
      url: agentInterface.url
    };
  }
  static agentProvider(agentProvider) {
    if (!agentProvider) {
      return void 0;
    }
    return {
      url: agentProvider.url,
      organization: agentProvider.organization
    };
  }
  static agentCapabilities(capabilities) {
    return {
      streaming: capabilities.streaming,
      pushNotifications: capabilities.pushNotifications,
      extensions: capabilities.extensions ? capabilities.extensions.map((e) => _ToProto.agentExtension(e)) : []
    };
  }
  static agentExtension(extension) {
    return {
      uri: extension.uri,
      description: extension.description ?? "",
      required: extension.required ?? false,
      params: extension.params
    };
  }
  static listTaskPushNotificationConfig(config) {
    return {
      configs: config.map((c) => _ToProto.taskPushNotificationConfig(c)),
      nextPageToken: ""
    };
  }
  static getTaskPushNotificationConfigParams(config) {
    return {
      name: generatePushNotificationConfigName(config.id, config.pushNotificationConfigId)
    };
  }
  static listTaskPushNotificationConfigParams(config) {
    return {
      parent: generateTaskName(config.id),
      pageToken: "",
      pageSize: 0
    };
  }
  static deleteTaskPushNotificationConfigParams(config) {
    return {
      name: generatePushNotificationConfigName(config.id, config.pushNotificationConfigId)
    };
  }
  static taskPushNotificationConfig(config) {
    return {
      name: generatePushNotificationConfigName(
        config.taskId,
        config.pushNotificationConfig.id ?? ""
      ),
      pushNotificationConfig: _ToProto.pushNotificationConfig(config.pushNotificationConfig)
    };
  }
  static taskPushNotificationConfigCreate(config) {
    return {
      parent: generateTaskName(config.taskId),
      config: _ToProto.taskPushNotificationConfig(config),
      configId: config.pushNotificationConfig.id
    };
  }
  static pushNotificationConfig(config) {
    if (!config) {
      return void 0;
    }
    return {
      id: config.id ?? "",
      url: config.url,
      token: config.token ?? "",
      authentication: _ToProto.pushNotificationAuthenticationInfo(config.authentication)
    };
  }
  static pushNotificationAuthenticationInfo(authInfo) {
    if (!authInfo) {
      return void 0;
    }
    return {
      schemes: authInfo.schemes,
      credentials: authInfo.credentials ?? ""
    };
  }
  static messageStreamResult(event) {
    if (event.kind === "message") {
      return {
        payload: {
          $case: "msg",
          value: _ToProto.message(event)
        }
      };
    } else if (event.kind === "task") {
      return {
        payload: {
          $case: "task",
          value: _ToProto.task(event)
        }
      };
    } else if (event.kind === "status-update") {
      return {
        payload: {
          $case: "statusUpdate",
          value: _ToProto.taskStatusUpdateEvent(event)
        }
      };
    } else if (event.kind === "artifact-update") {
      return {
        payload: {
          $case: "artifactUpdate",
          value: _ToProto.taskArtifactUpdateEvent(event)
        }
      };
    } else {
      throw A2AError.internalError("Invalid event type");
    }
  }
  static taskStatusUpdateEvent(event) {
    return {
      taskId: event.taskId,
      status: _ToProto.taskStatus(event.status),
      contextId: event.contextId,
      metadata: event.metadata,
      final: event.final
    };
  }
  static taskArtifactUpdateEvent(event) {
    return {
      taskId: event.taskId,
      artifact: _ToProto.artifact(event.artifact),
      contextId: event.contextId,
      metadata: event.metadata,
      append: event.append,
      lastChunk: event.lastChunk
    };
  }
  static messageSendResult(params) {
    if (params.kind === "message") {
      return {
        payload: {
          $case: "msg",
          value: _ToProto.message(params)
        }
      };
    } else if (params.kind === "task") {
      return {
        payload: {
          $case: "task",
          value: _ToProto.task(params)
        }
      };
    }
  }
  static message(message) {
    if (!message) {
      return void 0;
    }
    return {
      messageId: message.messageId,
      content: message.parts.map((p) => _ToProto.part(p)),
      contextId: message.contextId ?? "",
      taskId: message.taskId ?? "",
      role: _ToProto.role(message.role),
      metadata: message.metadata,
      extensions: message.extensions ?? []
    };
  }
  static role(role) {
    switch (role) {
      case "agent":
        return 2 /* ROLE_AGENT */;
      case "user":
        return 1 /* ROLE_USER */;
      default:
        throw A2AError.internalError(`Invalid role`);
    }
  }
  static task(task) {
    return {
      id: task.id,
      contextId: task.contextId,
      status: _ToProto.taskStatus(task.status),
      artifacts: task.artifacts?.map((a) => _ToProto.artifact(a)) ?? [],
      history: task.history?.map((m) => _ToProto.message(m)) ?? [],
      metadata: task.metadata
    };
  }
  static taskStatus(status) {
    return {
      state: _ToProto.taskState(status.state),
      update: _ToProto.message(status.message),
      timestamp: status.timestamp
    };
  }
  static artifact(artifact) {
    return {
      artifactId: artifact.artifactId,
      name: artifact.name ?? "",
      description: artifact.description ?? "",
      parts: artifact.parts.map((p) => _ToProto.part(p)),
      metadata: artifact.metadata,
      extensions: artifact.extensions ? artifact.extensions : []
    };
  }
  static taskState(state) {
    switch (state) {
      case "submitted":
        return 1 /* TASK_STATE_SUBMITTED */;
      case "working":
        return 2 /* TASK_STATE_WORKING */;
      case "input-required":
        return 6 /* TASK_STATE_INPUT_REQUIRED */;
      case "rejected":
        return 7 /* TASK_STATE_REJECTED */;
      case "auth-required":
        return 8 /* TASK_STATE_AUTH_REQUIRED */;
      case "completed":
        return 3 /* TASK_STATE_COMPLETED */;
      case "failed":
        return 4 /* TASK_STATE_FAILED */;
      case "canceled":
        return 5 /* TASK_STATE_CANCELLED */;
      case "unknown":
        return 0 /* TASK_STATE_UNSPECIFIED */;
      default:
        return -1 /* UNRECOGNIZED */;
    }
  }
  static part(part) {
    if (part.kind === "text") {
      return {
        part: { $case: "text", value: part.text }
      };
    }
    if (part.kind === "file") {
      let filePart;
      if ("uri" in part.file) {
        filePart = {
          file: { $case: "fileWithUri", value: part.file.uri },
          mimeType: part.file.mimeType
        };
      } else if ("bytes" in part.file) {
        filePart = {
          file: { $case: "fileWithBytes", value: Buffer.from(part.file.bytes, "base64") },
          mimeType: part.file.mimeType
        };
      } else {
        throw A2AError.internalError("Invalid file part");
      }
      return {
        part: { $case: "file", value: filePart }
      };
    }
    if (part.kind === "data") {
      return {
        part: { $case: "data", value: { data: part.data } }
      };
    }
    throw A2AError.internalError("Invalid part type");
  }
  static messageSendParams(params) {
    return {
      request: _ToProto.message(params.message),
      configuration: _ToProto.configuration(params.configuration),
      metadata: params.metadata
    };
  }
  static configuration(configuration) {
    if (!configuration) {
      return void 0;
    }
    return {
      blocking: configuration.blocking,
      acceptedOutputModes: configuration.acceptedOutputModes ?? [],
      pushNotification: _ToProto.pushNotificationConfig(configuration.pushNotificationConfig),
      historyLength: configuration.historyLength ?? 0
    };
  }
  static taskQueryParams(params) {
    return {
      name: generateTaskName(params.id),
      historyLength: params.historyLength ?? 0
    };
  }
  static cancelTaskRequest(params) {
    return {
      name: generateTaskName(params.id)
    };
  }
  static taskIdParams(params) {
    return {
      name: generateTaskName(params.id)
    };
  }
  static getAgentCardRequest() {
    return {};
  }
};

// src/client/transports/rest_transport.ts
var RestTransport = class _RestTransport {
  customFetchImpl;
  endpoint;
  constructor(options) {
    this.endpoint = options.endpoint.replace(/\/+$/, "");
    this.customFetchImpl = options.fetchImpl;
  }
  async getExtendedAgentCard(options) {
    const response = await this._sendRequest(
      "GET",
      "/v1/card",
      void 0,
      options,
      void 0,
      AgentCard
    );
    return FromProto.agentCard(response);
  }
  async sendMessage(params, options) {
    const requestBody = ToProto.messageSendParams(params);
    const response = await this._sendRequest(
      "POST",
      "/v1/message:send",
      requestBody,
      options,
      SendMessageRequest,
      SendMessageResponse
    );
    return FromProto.sendMessageResult(response);
  }
  async *sendMessageStream(params, options) {
    const protoParams = ToProto.messageSendParams(params);
    const requestBody = SendMessageRequest.toJSON(protoParams);
    yield* this._sendStreamingRequest("/v1/message:stream", requestBody, options);
  }
  async setTaskPushNotificationConfig(params, options) {
    const requestBody = ToProto.taskPushNotificationConfig(params);
    const response = await this._sendRequest(
      "POST",
      `/v1/tasks/${encodeURIComponent(params.taskId)}/pushNotificationConfigs`,
      requestBody,
      options,
      TaskPushNotificationConfig,
      TaskPushNotificationConfig
    );
    return FromProto.taskPushNotificationConfig(response);
  }
  async getTaskPushNotificationConfig(params, options) {
    const { pushNotificationConfigId } = params;
    if (!pushNotificationConfigId) {
      throw new Error(
        "pushNotificationConfigId is required for getTaskPushNotificationConfig with REST transport."
      );
    }
    const response = await this._sendRequest(
      "GET",
      `/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs/${encodeURIComponent(pushNotificationConfigId)}`,
      void 0,
      options,
      void 0,
      TaskPushNotificationConfig
    );
    return FromProto.taskPushNotificationConfig(response);
  }
  async listTaskPushNotificationConfig(params, options) {
    const response = await this._sendRequest(
      "GET",
      `/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs`,
      void 0,
      options,
      void 0,
      ListTaskPushNotificationConfigResponse
    );
    return FromProto.listTaskPushNotificationConfig(response);
  }
  async deleteTaskPushNotificationConfig(params, options) {
    await this._sendRequest(
      "DELETE",
      `/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs/${encodeURIComponent(params.pushNotificationConfigId)}`,
      void 0,
      options,
      void 0,
      void 0
    );
  }
  async getTask(params, options) {
    const queryParams = new URLSearchParams();
    if (params.historyLength !== void 0) {
      queryParams.set("historyLength", String(params.historyLength));
    }
    const queryString = queryParams.toString();
    const path = `/v1/tasks/${encodeURIComponent(params.id)}${queryString ? `?${queryString}` : ""}`;
    const response = await this._sendRequest(
      "GET",
      path,
      void 0,
      options,
      void 0,
      Task
    );
    return FromProto.task(response);
  }
  async cancelTask(params, options) {
    const response = await this._sendRequest(
      "POST",
      `/v1/tasks/${encodeURIComponent(params.id)}:cancel`,
      void 0,
      options,
      void 0,
      Task
    );
    return FromProto.task(response);
  }
  async *resubscribeTask(params, options) {
    yield* this._sendStreamingRequest(
      `/v1/tasks/${encodeURIComponent(params.id)}:subscribe`,
      void 0,
      options
    );
  }
  _fetch(...args) {
    if (this.customFetchImpl) {
      return this.customFetchImpl(...args);
    }
    if (typeof fetch === "function") {
      return fetch(...args);
    }
    throw new Error(
      "A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the RestTransportOptions."
    );
  }
  _buildHeaders(options, acceptHeader = "application/json") {
    return {
      ...options?.serviceParameters,
      "Content-Type": "application/json",
      Accept: acceptHeader
    };
  }
  async _sendRequest(method, path, body, options, requestType, responseType) {
    const url = `${this.endpoint}${path}`;
    const requestInit = {
      method,
      headers: this._buildHeaders(options),
      signal: options?.signal
    };
    if (body !== void 0 && method !== "GET") {
      if (!requestType) {
        throw new Error(
          `Bug: Request body provided for ${method} ${path} but no toJson serializer provided.`
        );
      }
      requestInit.body = JSON.stringify(requestType.toJSON(body));
    }
    const response = await this._fetch(url, requestInit);
    if (!response.ok) {
      await this._handleErrorResponse(response, path);
    }
    if (response.status === 204 || !responseType) {
      return void 0;
    }
    const result = await response.json();
    return responseType.fromJSON(result);
  }
  async _handleErrorResponse(response, path) {
    let errorBodyText = "(empty or non-JSON response)";
    let errorBody;
    try {
      errorBodyText = await response.text();
      if (errorBodyText) {
        errorBody = JSON.parse(errorBodyText);
      }
    } catch (e) {
      throw new Error(
        `HTTP error for ${path}! Status: ${response.status} ${response.statusText}. Response: ${errorBodyText}`,
        { cause: e }
      );
    }
    if (errorBody && typeof errorBody.code === "number") {
      throw _RestTransport.mapToError(errorBody);
    }
    throw new Error(
      `HTTP error for ${path}! Status: ${response.status} ${response.statusText}. Response: ${errorBodyText}`
    );
  }
  async *_sendStreamingRequest(path, body, options) {
    const url = `${this.endpoint}${path}`;
    const requestInit = {
      method: "POST",
      headers: this._buildHeaders(options, "text/event-stream"),
      signal: options?.signal
    };
    if (body !== void 0) {
      requestInit.body = JSON.stringify(body);
    }
    const response = await this._fetch(url, requestInit);
    if (!response.ok) {
      await this._handleErrorResponse(response, path);
    }
    const contentType = response.headers.get("Content-Type");
    if (!contentType?.startsWith("text/event-stream")) {
      throw new Error(
        `Invalid response Content-Type for SSE stream. Expected 'text/event-stream', got '${contentType}'.`
      );
    }
    for await (const event of parseSseStream(response)) {
      if (event.type === "error") {
        const errorData = JSON.parse(event.data);
        throw _RestTransport.mapToError(errorData);
      }
      yield this._processSseEventData(event.data);
    }
  }
  _processSseEventData(jsonData) {
    if (!jsonData.trim()) {
      throw new Error("Attempted to process empty SSE event data.");
    }
    try {
      const response = JSON.parse(jsonData);
      const protoResponse = StreamResponse.fromJSON(response);
      return FromProto.messageStreamResult(protoResponse);
    } catch (e) {
      console.error("Failed to parse SSE event data:", jsonData, e);
      throw new Error(
        `Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e instanceof Error && e.message || "Unknown error"}`
      );
    }
  }
  static mapToError(error) {
    switch (error.code) {
      case A2A_ERROR_CODE.TASK_NOT_FOUND:
        return new TaskNotFoundError(error.message);
      case A2A_ERROR_CODE.TASK_NOT_CANCELABLE:
        return new TaskNotCancelableError(error.message);
      case A2A_ERROR_CODE.PUSH_NOTIFICATION_NOT_SUPPORTED:
        return new PushNotificationNotSupportedError(error.message);
      case A2A_ERROR_CODE.UNSUPPORTED_OPERATION:
        return new UnsupportedOperationError(error.message);
      case A2A_ERROR_CODE.CONTENT_TYPE_NOT_SUPPORTED:
        return new ContentTypeNotSupportedError(error.message);
      case A2A_ERROR_CODE.INVALID_AGENT_RESPONSE:
        return new InvalidAgentResponseError(error.message);
      case A2A_ERROR_CODE.AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED:
        return new AuthenticatedExtendedCardNotConfiguredError(error.message);
      default:
        return new Error(
          `REST error: ${error.message} (Code: ${error.code})${error.data ? ` Data: ${JSON.stringify(error.data)}` : ""}`
        );
    }
  }
};
var RestTransportFactory = class _RestTransportFactory {
  constructor(options) {
    this.options = options;
  }
  static name = "HTTP+JSON";
  get protocolName() {
    return _RestTransportFactory.name;
  }
  async create(url, _agentCard) {
    return new RestTransport({
      endpoint: url,
      fetchImpl: this.options?.fetchImpl
    });
  }
};

// src/client/factory.ts
var ClientFactoryOptions = {
  /**
   * SDK default options for {@link ClientFactory}.
   */
  default: {
    transports: [new JsonRpcTransportFactory(), new RestTransportFactory()]
  },
  /**
   * Creates new options by merging an original and an override object.
   * Transports are merged based on `TransportFactory.protocolName`,
   * interceptors are concatenated, other fields are overriden.
   *
   * @example
   * ```ts
   * const options = ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
   *  transports: [new MyCustomTransportFactory()], // adds a custom transport
   *  clientConfig: { interceptors: [new MyInterceptor()] }, // adds a custom interceptor
   * });
   * ```
   */
  createFrom(original, overrides) {
    return {
      ...original,
      ...overrides,
      transports: mergeTransports(original.transports, overrides.transports),
      clientConfig: {
        ...original.clientConfig ?? {},
        ...overrides.clientConfig ?? {},
        interceptors: mergeArrays(
          original.clientConfig?.interceptors,
          overrides.clientConfig?.interceptors
        ),
        acceptedOutputModes: overrides.clientConfig?.acceptedOutputModes ?? original.clientConfig?.acceptedOutputModes
      },
      preferredTransports: overrides.preferredTransports ?? original.preferredTransports
    };
  }
};
var ClientFactory = class {
  constructor(options = ClientFactoryOptions.default) {
    this.options = options;
    if (!options.transports || options.transports.length === 0) {
      throw new Error("No transports provided");
    }
    this.transportsByName = transportsByName(options.transports);
    for (const transport of options.preferredTransports ?? []) {
      if (!this.transportsByName.has(transport)) {
        throw new Error(
          `Unknown preferred transport: ${transport}, available transports: ${[...this.transportsByName.keys()].join()}`
        );
      }
    }
    this.agentCardResolver = options.cardResolver ?? AgentCardResolver.default;
  }
  transportsByName;
  agentCardResolver;
  /**
   * Creates a new client from the provided agent card.
   */
  async createFromAgentCard(agentCard) {
    const agentCardPreferred = agentCard.preferredTransport ?? JsonRpcTransportFactory.name;
    const additionalInterfaces = agentCard.additionalInterfaces ?? [];
    const urlsPerAgentTransports = new CaseInsensitiveMap([
      [agentCardPreferred, agentCard.url],
      ...additionalInterfaces.map((i) => [i.transport, i.url])
    ]);
    const transportsByPreference = [
      ...this.options.preferredTransports ?? [],
      agentCardPreferred,
      ...additionalInterfaces.map((i) => i.transport)
    ];
    for (const transport of transportsByPreference) {
      const url = urlsPerAgentTransports.get(transport);
      const factory = this.transportsByName.get(transport);
      if (factory && url) {
        return new Client(
          await factory.create(url, agentCard),
          agentCard,
          this.options.clientConfig
        );
      }
    }
    throw new Error(
      "No compatible transport found, available transports: " + [...this.transportsByName.keys()].join()
    );
  }
  /**
   * Downloads agent card using AgentCardResolver from options
   * and creates a new client from the downloaded card.
   *
   * @example
   * ```ts
   * const factory = new ClientFactory(); // use default options and default {@link AgentCardResolver}.
   * const client1 = await factory.createFromUrl('https://example.com'); // /.well-known/agent-card.json is used by default
   * const client2 = await factory.createFromUrl('https://example.com', '/my-agent-card.json'); // specify custom path
   * const client3 = await factory.createFromUrl('https://example.com/my-agent-card.json', ''); // specify full URL and set path to empty
   * ```
   */
  async createFromUrl(baseUrl, path) {
    const agentCard = await this.agentCardResolver.resolve(baseUrl, path);
    return this.createFromAgentCard(agentCard);
  }
};
function mergeTransports(original, overrides) {
  if (!overrides) {
    return original;
  }
  const result = transportsByName(original);
  const overridesByName = transportsByName(overrides);
  for (const [name, factory] of overridesByName) {
    result.set(name, factory);
  }
  return Array.from(result.values());
}
function transportsByName(transports) {
  const result = new CaseInsensitiveMap();
  if (!transports) {
    return result;
  }
  for (const t of transports) {
    if (result.has(t.protocolName)) {
      throw new Error(`Duplicate protocol name: ${t.protocolName}`);
    }
    result.set(t.protocolName, t);
  }
  return result;
}
function mergeArrays(a1, a2) {
  if (!a1 && !a2) {
    return void 0;
  }
  return [...a1 ?? [], ...a2 ?? []];
}
var CaseInsensitiveMap = class extends Map {
  normalizeKey(key) {
    return key.toUpperCase();
  }
  set(key, value) {
    return super.set(this.normalizeKey(key), value);
  }
  get(key) {
    return super.get(this.normalizeKey(key));
  }
  has(key) {
    return super.has(this.normalizeKey(key));
  }
  delete(key) {
    return super.delete(this.normalizeKey(key));
  }
};

// src/extensions.ts
var Extensions = {
  /**
   * Creates new {@link Extensions} from `current` and `additional`.
   * If `current` already contains `additional` it is returned unmodified.
   */
  createFrom: (current, additional) => {
    if (current?.includes(additional)) {
      return current;
    }
    return [...current ?? [], additional];
  },
  /**
   * Creates {@link Extensions} from comma separated extensions identifiers as per
   * https://a2a-protocol.org/latest/specification/#326-service-parameters.
   * Parses the output of `toServiceParameter`.
   */
  parseServiceParameter: (value) => {
    if (!value) {
      return [];
    }
    const unique = new Set(
      value.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
    );
    return Array.from(unique);
  },
  /**
   * Converts {@link Extensions} to comma separated extensions identifiers as per
   * https://a2a-protocol.org/latest/specification/#326-service-parameters.
   */
  toServiceParameter: (value) => {
    return value.join(",");
  }
};

// src/client/service-parameters.ts
var ServiceParameters = {
  create(...updates) {
    return ServiceParameters.createFrom(void 0, ...updates);
  },
  createFrom: (serviceParameters, ...updates) => {
    const result = serviceParameters ? { ...serviceParameters } : {};
    for (const update of updates) {
      update(result);
    }
    return result;
  }
};
function withA2AExtensions(...extensions) {
  return (parameters) => {
    parameters[HTTP_EXTENSION_HEADER] = Extensions.toServiceParameter(extensions);
  };
}

// src/client/context.ts
var ClientCallContext = {
  /**
   * Create a new {@link ClientCallContext} with optional updates applied.
   */
  create: (...updates) => {
    return ClientCallContext.createFrom(void 0, ...updates);
  },
  /**
   * Create a new {@link ClientCallContext} based on an existing one with updates applied.
   */
  createFrom: (context, ...updates) => {
    const result = context ? { ...context } : {};
    for (const update of updates) {
      update(result);
    }
    return result;
  }
};
var ClientCallContextKey = class {
  symbol;
  constructor(description) {
    this.symbol = Symbol(description);
  }
  set(value) {
    return (context) => {
      context[this.symbol] = value;
    };
  }
  get(context) {
    return context[this.symbol];
  }
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  A2AClient,
  AgentCardResolver,
  AuthenticatedExtendedCardNotConfiguredError,
  Client,
  ClientCallContext,
  ClientCallContextKey,
  ClientFactory,
  ClientFactoryOptions,
  ContentTypeNotSupportedError,
  DefaultAgentCardResolver,
  InvalidAgentResponseError,
  JsonRpcTransport,
  JsonRpcTransportFactory,
  PushNotificationNotSupportedError,
  RestTransport,
  RestTransportFactory,
  ServiceParameters,
  TaskNotCancelableError,
  TaskNotFoundError,
  UnsupportedOperationError,
  createAuthenticatingFetchWithRetry,
  withA2AExtensions
});
