import {
  JsonRpcTransportHandler
} from "../chunk-S53FFHPM.js";
import {
  ServerCallContext,
  UnauthenticatedUser
} from "../chunk-F6ACNKFR.js";
import "../chunk-ZX6KNMCP.js";
import {
  A2AError
} from "../chunk-UHZEIZLS.js";

// src/server/agent_execution/request_context.ts
var RequestContext = class {
  userMessage;
  taskId;
  contextId;
  task;
  referenceTasks;
  context;
  constructor(userMessage, taskId, contextId, task, referenceTasks, context) {
    this.userMessage = userMessage;
    this.taskId = taskId;
    this.contextId = contextId;
    this.task = task;
    this.referenceTasks = referenceTasks;
    this.context = context;
  }
};

// src/server/events/execution_event_bus.ts
var CustomEventImpl = typeof CustomEvent !== "undefined" ? CustomEvent : class CustomEventPolyfill extends Event {
  detail;
  constructor(type, eventInitDict) {
    super(type, eventInitDict);
    this.detail = eventInitDict?.detail ?? null;
  }
};
function isAgentExecutionCustomEvent(e) {
  return e instanceof CustomEventImpl;
}
var DefaultExecutionEventBus = class extends EventTarget {
  // Separate storage for each event type - both use the interface's Listener type
  // but are invoked differently (with event payload vs. no arguments)
  eventListeners = /* @__PURE__ */ new Map();
  finishedListeners = /* @__PURE__ */ new Map();
  publish(event) {
    this.dispatchEvent(new CustomEventImpl("event", { detail: event }));
  }
  finished() {
    this.dispatchEvent(new Event("finished"));
  }
  /**
   * EventEmitter-compatible 'on' method.
   * Wraps the listener to extract event detail from CustomEvent.
   * Supports multiple registrations of the same listener (like EventEmitter).
   * @param eventName The event name to listen for.
   * @param listener The callback function to invoke when the event is emitted.
   * @returns This instance for method chaining.
   */
  on(eventName, listener) {
    if (eventName === "event") {
      this.addEventListenerInternal(listener);
    } else {
      this.addFinishedListenerInternal(listener);
    }
    return this;
  }
  /**
   * EventEmitter-compatible 'off' method.
   * Uses the stored wrapped listener for proper removal.
   * Removes at most one instance of a listener per call (like EventEmitter).
   * @param eventName The event name to stop listening for.
   * @param listener The callback function to remove.
   * @returns This instance for method chaining.
   */
  off(eventName, listener) {
    if (eventName === "event") {
      this.removeEventListenerInternal(listener);
    } else {
      this.removeFinishedListenerInternal(listener);
    }
    return this;
  }
  /**
   * EventEmitter-compatible 'once' method.
   * Listener is automatically removed after first invocation.
   * Supports multiple registrations of the same listener (like EventEmitter).
   * @param eventName The event name to listen for once.
   * @param listener The callback function to invoke when the event is emitted.
   * @returns This instance for method chaining.
   */
  once(eventName, listener) {
    if (eventName === "event") {
      this.addEventListenerOnceInternal(listener);
    } else {
      this.addFinishedListenerOnceInternal(listener);
    }
    return this;
  }
  /**
   * EventEmitter-compatible 'removeAllListeners' method.
   * Removes all listeners for a specific event or all events.
   * @param eventName Optional event name to remove listeners for. If omitted, removes all.
   * @returns This instance for method chaining.
   */
  removeAllListeners(eventName) {
    if (eventName === void 0 || eventName === "event") {
      for (const wrappedListeners of this.eventListeners.values()) {
        for (const wrapped of wrappedListeners) {
          this.removeEventListener("event", wrapped);
        }
      }
      this.eventListeners.clear();
    }
    if (eventName === void 0 || eventName === "finished") {
      for (const wrappedListeners of this.finishedListeners.values()) {
        for (const wrapped of wrappedListeners) {
          this.removeEventListener("finished", wrapped);
        }
      }
      this.finishedListeners.clear();
    }
    return this;
  }
  // ========================
  // Helper methods for listener tracking
  // ========================
  /**
   * Adds a wrapped listener to the tracking map.
   */
  trackListener(listenerMap, listener, wrapped) {
    const existing = listenerMap.get(listener);
    if (existing) {
      existing.push(wrapped);
    } else {
      listenerMap.set(listener, [wrapped]);
    }
  }
  /**
   * Removes a wrapped listener from the tracking map (for once cleanup).
   */
  untrackWrappedListener(listenerMap, listener, wrapped) {
    const wrappedList = listenerMap.get(listener);
    if (wrappedList && wrappedList.length > 0) {
      const index = wrappedList.indexOf(wrapped);
      if (index !== -1) {
        wrappedList.splice(index, 1);
        if (wrappedList.length === 0) {
          listenerMap.delete(listener);
        }
      }
    }
  }
  // ========================
  // Internal methods for 'event' listeners
  // ========================
  addEventListenerInternal(listener) {
    const wrapped = (e) => {
      if (!isAgentExecutionCustomEvent(e)) {
        throw new Error('Internal error: expected CustomEvent for "event" type');
      }
      listener.call(this, e.detail);
    };
    this.trackListener(this.eventListeners, listener, wrapped);
    this.addEventListener("event", wrapped);
  }
  removeEventListenerInternal(listener) {
    const wrappedList = this.eventListeners.get(listener);
    if (wrappedList && wrappedList.length > 0) {
      const wrapped = wrappedList.pop();
      if (wrappedList.length === 0) {
        this.eventListeners.delete(listener);
      }
      this.removeEventListener("event", wrapped);
    }
  }
  addEventListenerOnceInternal(listener) {
    const wrapped = (e) => {
      if (!isAgentExecutionCustomEvent(e)) {
        throw new Error('Internal error: expected CustomEvent for "event" type');
      }
      this.untrackWrappedListener(this.eventListeners, listener, wrapped);
      listener.call(this, e.detail);
    };
    this.trackListener(this.eventListeners, listener, wrapped);
    this.addEventListener("event", wrapped, { once: true });
  }
  // ========================
  // Internal methods for 'finished' listeners
  // ========================
  // The interface declares listeners as (event: AgentExecutionEvent) => void,
  // but for 'finished' events they are invoked with no arguments (EventEmitter behavior).
  // We use Function.prototype.call to invoke with `this` as the event bus (matching
  // EventEmitter semantics) and no arguments, which is type-safe.
  addFinishedListenerInternal(listener) {
    const wrapped = () => {
      listener.call(this);
    };
    this.trackListener(this.finishedListeners, listener, wrapped);
    this.addEventListener("finished", wrapped);
  }
  removeFinishedListenerInternal(listener) {
    const wrappedList = this.finishedListeners.get(listener);
    if (wrappedList && wrappedList.length > 0) {
      const wrapped = wrappedList.pop();
      if (wrappedList.length === 0) {
        this.finishedListeners.delete(listener);
      }
      this.removeEventListener("finished", wrapped);
    }
  }
  addFinishedListenerOnceInternal(listener) {
    const wrapped = () => {
      this.untrackWrappedListener(this.finishedListeners, listener, wrapped);
      listener.call(this);
    };
    this.trackListener(this.finishedListeners, listener, wrapped);
    this.addEventListener("finished", wrapped, { once: true });
  }
};

// src/server/events/execution_event_bus_manager.ts
var DefaultExecutionEventBusManager = class {
  taskIdToBus = /* @__PURE__ */ new Map();
  /**
   * Creates or retrieves an existing ExecutionEventBus based on the taskId.
   * @param taskId The ID of the task.
   * @returns An instance of ExecutionEventBus.
   */
  createOrGetByTaskId(taskId) {
    if (!this.taskIdToBus.has(taskId)) {
      this.taskIdToBus.set(taskId, new DefaultExecutionEventBus());
    }
    return this.taskIdToBus.get(taskId);
  }
  /**
   * Retrieves an existing ExecutionEventBus based on the taskId.
   * @param taskId The ID of the task.
   * @returns An instance of ExecutionEventBus or undefined if not found.
   */
  getByTaskId(taskId) {
    return this.taskIdToBus.get(taskId);
  }
  /**
   * Removes the event bus for a given taskId.
   * This should be called when an execution flow is complete to free resources.
   * @param taskId The ID of the task.
   */
  cleanupByTaskId(taskId) {
    const bus = this.taskIdToBus.get(taskId);
    if (bus) {
      bus.removeAllListeners();
    }
    this.taskIdToBus.delete(taskId);
  }
};

// src/server/events/execution_event_queue.ts
var ExecutionEventQueue = class {
  eventBus;
  eventQueue = [];
  resolvePromise;
  stopped = false;
  constructor(eventBus) {
    this.eventBus = eventBus;
    this.eventBus.on("event", this.handleEvent);
    this.eventBus.on("finished", this.handleFinished);
  }
  handleEvent = (event) => {
    if (this.stopped) return;
    this.eventQueue.push(event);
    if (this.resolvePromise) {
      this.resolvePromise();
      this.resolvePromise = void 0;
    }
  };
  handleFinished = () => {
    this.stop();
  };
  /**
   * Provides an async generator that yields events from the event bus.
   * Stops when a Message event is received or a TaskStatusUpdateEvent with final=true is received.
   */
  async *events() {
    while (!this.stopped || this.eventQueue.length > 0) {
      if (this.eventQueue.length > 0) {
        const event = this.eventQueue.shift();
        yield event;
        if (event.kind === "message" || event.kind === "status-update" && event.final) {
          this.handleFinished();
          break;
        }
      } else if (!this.stopped) {
        await new Promise((resolve) => {
          this.resolvePromise = resolve;
        });
      }
    }
  }
  /**
   * Stops the event queue from processing further events.
   */
  stop() {
    this.stopped = true;
    if (this.resolvePromise) {
      this.resolvePromise();
      this.resolvePromise = void 0;
    }
    this.eventBus.off("event", this.handleEvent);
    this.eventBus.off("finished", this.handleFinished);
  }
};

// src/server/request_handler/default_request_handler.ts
import { v4 as uuidv4 } from "uuid";

// src/server/result_manager.ts
var ResultManager = class {
  taskStore;
  serverCallContext;
  currentTask;
  latestUserMessage;
  // To add to history if a new task is created
  finalMessageResult;
  // Stores the message if it's the final result
  constructor(taskStore, serverCallContext) {
    this.taskStore = taskStore;
    this.serverCallContext = serverCallContext;
  }
  setContext(latestUserMessage) {
    this.latestUserMessage = latestUserMessage;
  }
  /**
   * Processes an agent execution event and updates the task store.
   * @param event The agent execution event.
   */
  async processEvent(event) {
    if (event.kind === "message") {
      this.finalMessageResult = event;
    } else if (event.kind === "task") {
      const taskEvent = event;
      this.currentTask = { ...taskEvent };
      if (this.latestUserMessage) {
        if (!this.currentTask.history?.find(
          (msg) => msg.messageId === this.latestUserMessage.messageId
        )) {
          this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
        }
      }
      await this.saveCurrentTask();
    } else if (event.kind === "status-update") {
      const updateEvent = event;
      if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
        this.currentTask.status = updateEvent.status;
        if (updateEvent.status.message) {
          if (!this.currentTask.history?.find(
            (msg) => msg.messageId === updateEvent.status.message.messageId
          )) {
            this.currentTask.history = [
              ...this.currentTask.history || [],
              updateEvent.status.message
            ];
          }
        }
        await this.saveCurrentTask();
      } else if (!this.currentTask && updateEvent.taskId) {
        const loaded = await this.taskStore.load(updateEvent.taskId, this.serverCallContext);
        if (loaded) {
          this.currentTask = loaded;
          this.currentTask.status = updateEvent.status;
          if (updateEvent.status.message) {
            if (!this.currentTask.history?.find(
              (msg) => msg.messageId === updateEvent.status.message.messageId
            )) {
              this.currentTask.history = [
                ...this.currentTask.history || [],
                updateEvent.status.message
              ];
            }
          }
          await this.saveCurrentTask();
        } else {
          console.warn(
            `ResultManager: Received status update for unknown task ${updateEvent.taskId}`
          );
        }
      }
    } else if (event.kind === "artifact-update") {
      const artifactEvent = event;
      if (this.currentTask && this.currentTask.id === artifactEvent.taskId) {
        if (!this.currentTask.artifacts) {
          this.currentTask.artifacts = [];
        }
        const existingArtifactIndex = this.currentTask.artifacts.findIndex(
          (art) => art.artifactId === artifactEvent.artifact.artifactId
        );
        if (existingArtifactIndex !== -1) {
          if (artifactEvent.append) {
            const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
            existingArtifact.parts.push(...artifactEvent.artifact.parts);
            if (artifactEvent.artifact.description)
              existingArtifact.description = artifactEvent.artifact.description;
            if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
            if (artifactEvent.artifact.metadata)
              existingArtifact.metadata = {
                ...existingArtifact.metadata,
                ...artifactEvent.artifact.metadata
              };
          } else {
            this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
          }
        } else {
          this.currentTask.artifacts.push(artifactEvent.artifact);
        }
        await this.saveCurrentTask();
      } else if (!this.currentTask && artifactEvent.taskId) {
        const loaded = await this.taskStore.load(artifactEvent.taskId, this.serverCallContext);
        if (loaded) {
          this.currentTask = loaded;
          if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
          const existingArtifactIndex = this.currentTask.artifacts.findIndex(
            (art) => art.artifactId === artifactEvent.artifact.artifactId
          );
          if (existingArtifactIndex !== -1) {
            if (artifactEvent.append) {
              this.currentTask.artifacts[existingArtifactIndex].parts.push(
                ...artifactEvent.artifact.parts
              );
            } else {
              this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
            }
          } else {
            this.currentTask.artifacts.push(artifactEvent.artifact);
          }
          await this.saveCurrentTask();
        } else {
          console.warn(
            `ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`
          );
        }
      }
    }
  }
  async saveCurrentTask() {
    if (this.currentTask) {
      await this.taskStore.save(this.currentTask, this.serverCallContext);
    }
  }
  /**
   * Gets the final result, which could be a Message or a Task.
   * This should be called after the event stream has been fully processed.
   * @returns The final Message or the current Task.
   */
  getFinalResult() {
    if (this.finalMessageResult) {
      return this.finalMessageResult;
    }
    return this.currentTask;
  }
  /**
   * Gets the task currently being managed by this ResultManager instance.
   * This task could be one that was started with or one created during agent execution.
   * @returns The current Task or undefined if no task is active.
   */
  getCurrentTask() {
    return this.currentTask;
  }
};

// src/server/push_notification/push_notification_store.ts
var InMemoryPushNotificationStore = class {
  store = /* @__PURE__ */ new Map();
  async save(taskId, pushNotificationConfig) {
    const configs = this.store.get(taskId) || [];
    if (!pushNotificationConfig.id) {
      pushNotificationConfig.id = taskId;
    }
    const existingIndex = configs.findIndex((config) => config.id === pushNotificationConfig.id);
    if (existingIndex !== -1) {
      configs.splice(existingIndex, 1);
    }
    configs.push(pushNotificationConfig);
    this.store.set(taskId, configs);
  }
  async load(taskId) {
    const configs = this.store.get(taskId);
    return configs || [];
  }
  async delete(taskId, configId) {
    if (configId === void 0) {
      configId = taskId;
    }
    const configs = this.store.get(taskId);
    if (!configs) {
      return;
    }
    const configIndex = configs.findIndex((config) => config.id === configId);
    if (configIndex !== -1) {
      configs.splice(configIndex, 1);
    }
    if (configs.length === 0) {
      this.store.delete(taskId);
    } else {
      this.store.set(taskId, configs);
    }
  }
};

// src/server/push_notification/default_push_notification_sender.ts
var DefaultPushNotificationSender = class {
  pushNotificationStore;
  notificationChain;
  options;
  constructor(pushNotificationStore, options = {}) {
    this.pushNotificationStore = pushNotificationStore;
    this.notificationChain = /* @__PURE__ */ new Map();
    this.options = {
      timeout: 5e3,
      tokenHeaderName: "X-A2A-Notification-Token",
      ...options
    };
  }
  async send(task) {
    const pushConfigs = await this.pushNotificationStore.load(task.id);
    if (!pushConfigs || pushConfigs.length === 0) {
      return;
    }
    const lastPromise = this.notificationChain.get(task.id) ?? Promise.resolve();
    const newPromise = lastPromise.then(async () => {
      const dispatches = pushConfigs.map(async (pushConfig) => {
        try {
          await this._dispatchNotification(task, pushConfig);
        } catch (error) {
          console.error(
            `Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`,
            error
          );
        }
      });
      await Promise.all(dispatches);
    });
    this.notificationChain.set(task.id, newPromise);
    return newPromise.finally(() => {
      if (this.notificationChain.get(task.id) === newPromise) {
        this.notificationChain.delete(task.id);
      }
    });
  }
  async _dispatchNotification(task, pushConfig) {
    const url = pushConfig.url;
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.options.timeout);
    try {
      const headers = {
        "Content-Type": "application/json"
      };
      if (pushConfig.token) {
        headers[this.options.tokenHeaderName] = pushConfig.token;
      }
      const response = await fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(task),
        signal: controller.signal
      });
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      console.info(`Push notification sent for task_id=${task.id} to URL: ${url}`);
    } finally {
      clearTimeout(timeoutId);
    }
  }
};

// src/server/request_handler/default_request_handler.ts
var terminalStates = ["completed", "failed", "canceled", "rejected"];
var DefaultRequestHandler = class {
  agentCard;
  taskStore;
  agentExecutor;
  eventBusManager;
  pushNotificationStore;
  pushNotificationSender;
  extendedAgentCardProvider;
  constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCardProvider) {
    this.agentCard = agentCard;
    this.taskStore = taskStore;
    this.agentExecutor = agentExecutor;
    this.eventBusManager = eventBusManager;
    this.extendedAgentCardProvider = extendedAgentCardProvider;
    if (agentCard.capabilities.pushNotifications) {
      this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
      this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
    }
  }
  async getAgentCard() {
    return this.agentCard;
  }
  async getAuthenticatedExtendedAgentCard(context) {
    if (!this.agentCard.supportsAuthenticatedExtendedCard) {
      throw A2AError.unsupportedOperation("Agent does not support authenticated extended card.");
    }
    if (!this.extendedAgentCardProvider) {
      throw A2AError.authenticatedExtendedCardNotConfigured();
    }
    if (typeof this.extendedAgentCardProvider === "function") {
      return this.extendedAgentCardProvider(context);
    }
    if (context?.user?.isAuthenticated) {
      return this.extendedAgentCardProvider;
    }
    return this.agentCard;
  }
  async _createRequestContext(incomingMessage, context) {
    let task;
    let referenceTasks;
    if (incomingMessage.taskId) {
      task = await this.taskStore.load(incomingMessage.taskId, context);
      if (!task) {
        throw A2AError.taskNotFound(incomingMessage.taskId);
      }
      if (terminalStates.includes(task.status.state)) {
        throw A2AError.invalidRequest(
          `Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`
        );
      }
      task.history = [...task.history || [], incomingMessage];
      await this.taskStore.save(task, context);
    }
    const taskId = incomingMessage.taskId || uuidv4();
    if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
      referenceTasks = [];
      for (const refId of incomingMessage.referenceTaskIds) {
        const refTask = await this.taskStore.load(refId, context);
        if (refTask) {
          referenceTasks.push(refTask);
        } else {
          console.warn(`Reference task ${refId} not found.`);
        }
      }
    }
    const contextId = incomingMessage.contextId || task?.contextId || uuidv4();
    if (context?.requestedExtensions) {
      const agentCard = await this.getAgentCard();
      const exposedExtensions = new Set(
        agentCard.capabilities.extensions?.map((ext) => ext.uri) || []
      );
      const validExtensions = context.requestedExtensions.filter(
        (extension) => exposedExtensions.has(extension)
      );
      context = new ServerCallContext(validExtensions, context.user);
    }
    const messageForContext = {
      ...incomingMessage,
      contextId,
      taskId
    };
    return new RequestContext(messageForContext, taskId, contextId, task, referenceTasks, context);
  }
  async _processEvents(taskId, resultManager, eventQueue, context, options) {
    let firstResultSent = false;
    try {
      for await (const event of eventQueue.events()) {
        await resultManager.processEvent(event);
        try {
          await this._sendPushNotificationIfNeeded(event, context);
        } catch (error) {
          console.error(`Error sending push notification: ${error}`);
        }
        if (options?.firstResultResolver && !firstResultSent) {
          let firstResult;
          if (event.kind === "message") {
            firstResult = event;
          } else {
            firstResult = resultManager.getCurrentTask();
          }
          if (firstResult) {
            options.firstResultResolver(firstResult);
            firstResultSent = true;
          }
        }
      }
      if (options?.firstResultRejector && !firstResultSent) {
        options.firstResultRejector(
          A2AError.internalError("Execution finished before a message or task was produced.")
        );
      }
    } catch (error) {
      console.error(`Event processing loop failed for task ${taskId}:`, error);
      this._handleProcessingError(
        error,
        resultManager,
        firstResultSent,
        taskId,
        options?.firstResultRejector
      );
    } finally {
      this.eventBusManager.cleanupByTaskId(taskId);
    }
  }
  async sendMessage(params, context) {
    const incomingMessage = params.message;
    if (!incomingMessage.messageId) {
      throw A2AError.invalidParams("message.messageId is required.");
    }
    const isBlocking = params.configuration?.blocking !== false;
    const resultManager = new ResultManager(this.taskStore, context);
    resultManager.setContext(incomingMessage);
    const requestContext = await this._createRequestContext(incomingMessage, context);
    const taskId = requestContext.taskId;
    const finalMessageForAgent = requestContext.userMessage;
    if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
      await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
    }
    const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
    const eventQueue = new ExecutionEventQueue(eventBus);
    this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
      console.error(`Agent execution failed for message ${finalMessageForAgent.messageId}:`, err);
      const errorTask = {
        id: requestContext.task?.id || uuidv4(),
        // Use existing task ID or generate new
        contextId: finalMessageForAgent.contextId,
        status: {
          state: "failed",
          message: {
            kind: "message",
            role: "agent",
            messageId: uuidv4(),
            parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
            taskId: requestContext.task?.id,
            contextId: finalMessageForAgent.contextId
          },
          timestamp: (/* @__PURE__ */ new Date()).toISOString()
        },
        history: requestContext.task?.history ? [...requestContext.task.history] : [],
        kind: "task"
      };
      if (finalMessageForAgent) {
        if (!errorTask.history?.find((m) => m.messageId === finalMessageForAgent.messageId)) {
          errorTask.history?.push(finalMessageForAgent);
        }
      }
      eventBus.publish(errorTask);
      eventBus.publish({
        // And publish a final status update
        kind: "status-update",
        taskId: errorTask.id,
        contextId: errorTask.contextId,
        status: errorTask.status,
        final: true
      });
      eventBus.finished();
    });
    if (isBlocking) {
      await this._processEvents(taskId, resultManager, eventQueue, context);
      const finalResult = resultManager.getFinalResult();
      if (!finalResult) {
        throw A2AError.internalError(
          "Agent execution finished without a result, and no task context found."
        );
      }
      return finalResult;
    } else {
      return new Promise((resolve, reject) => {
        this._processEvents(taskId, resultManager, eventQueue, context, {
          firstResultResolver: resolve,
          firstResultRejector: reject
        });
      });
    }
  }
  async *sendMessageStream(params, context) {
    const incomingMessage = params.message;
    if (!incomingMessage.messageId) {
      throw A2AError.invalidParams("message.messageId is required for streaming.");
    }
    const resultManager = new ResultManager(this.taskStore, context);
    resultManager.setContext(incomingMessage);
    const requestContext = await this._createRequestContext(incomingMessage, context);
    const taskId = requestContext.taskId;
    const finalMessageForAgent = requestContext.userMessage;
    const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
    const eventQueue = new ExecutionEventQueue(eventBus);
    if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
      await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
    }
    this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
      console.error(
        `Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,
        err
      );
      const errorTaskStatus = {
        kind: "status-update",
        taskId: requestContext.task?.id || uuidv4(),
        // Use existing or a placeholder
        contextId: finalMessageForAgent.contextId,
        status: {
          state: "failed",
          message: {
            kind: "message",
            role: "agent",
            messageId: uuidv4(),
            parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
            taskId: requestContext.task?.id,
            contextId: finalMessageForAgent.contextId
          },
          timestamp: (/* @__PURE__ */ new Date()).toISOString()
        },
        final: true
        // This will terminate the stream for the client
      };
      eventBus.publish(errorTaskStatus);
    });
    try {
      for await (const event of eventQueue.events()) {
        await resultManager.processEvent(event);
        await this._sendPushNotificationIfNeeded(event, context);
        yield event;
      }
    } finally {
      this.eventBusManager.cleanupByTaskId(taskId);
    }
  }
  async getTask(params, context) {
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    if (params.historyLength !== void 0 && params.historyLength >= 0) {
      if (task.history) {
        task.history = task.history.slice(-params.historyLength);
      }
    } else {
      task.history = [];
    }
    return task;
  }
  async cancelTask(params, context) {
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    const nonCancelableStates = ["completed", "failed", "canceled", "rejected"];
    if (nonCancelableStates.includes(task.status.state)) {
      throw A2AError.taskNotCancelable(params.id);
    }
    const eventBus = this.eventBusManager.getByTaskId(params.id);
    if (eventBus) {
      const eventQueue = new ExecutionEventQueue(eventBus);
      await this.agentExecutor.cancelTask(params.id, eventBus);
      await this._processEvents(
        params.id,
        new ResultManager(this.taskStore, context),
        eventQueue,
        context
      );
    } else {
      task.status = {
        state: "canceled",
        message: {
          // Optional: Add a system message indicating cancellation
          kind: "message",
          role: "agent",
          messageId: uuidv4(),
          parts: [{ kind: "text", text: "Task cancellation requested by user." }],
          taskId: task.id,
          contextId: task.contextId
        },
        timestamp: (/* @__PURE__ */ new Date()).toISOString()
      };
      task.history = [...task.history || [], task.status.message];
      await this.taskStore.save(task, context);
    }
    const latestTask = await this.taskStore.load(params.id, context);
    if (!latestTask) {
      throw A2AError.internalError(`Task ${params.id} not found after cancellation.`);
    }
    if (latestTask.status.state != "canceled") {
      throw A2AError.taskNotCancelable(params.id);
    }
    return latestTask;
  }
  async setTaskPushNotificationConfig(params, context) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw A2AError.pushNotificationNotSupported();
    }
    const task = await this.taskStore.load(params.taskId, context);
    if (!task) {
      throw A2AError.taskNotFound(params.taskId);
    }
    const { taskId, pushNotificationConfig } = params;
    if (!pushNotificationConfig.id) {
      pushNotificationConfig.id = taskId;
    }
    await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
    return params;
  }
  async getTaskPushNotificationConfig(params, context) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw A2AError.pushNotificationNotSupported();
    }
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    const configs = await this.pushNotificationStore?.load(params.id) || [];
    if (configs.length === 0) {
      throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
    }
    let configId;
    if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
      configId = params.pushNotificationConfigId;
    } else {
      configId = params.id;
    }
    const config = configs.find((c) => c.id === configId);
    if (!config) {
      throw A2AError.internalError(
        `Push notification config with id '${configId}' not found for task ${params.id}.`
      );
    }
    return { taskId: params.id, pushNotificationConfig: config };
  }
  async listTaskPushNotificationConfigs(params, context) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw A2AError.pushNotificationNotSupported();
    }
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    const configs = await this.pushNotificationStore?.load(params.id) || [];
    return configs.map((config) => ({
      taskId: params.id,
      pushNotificationConfig: config
    }));
  }
  async deleteTaskPushNotificationConfig(params, context) {
    if (!this.agentCard.capabilities.pushNotifications) {
      throw A2AError.pushNotificationNotSupported();
    }
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    const { id: taskId, pushNotificationConfigId } = params;
    await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
  }
  async *resubscribe(params, context) {
    if (!this.agentCard.capabilities.streaming) {
      throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
    }
    const task = await this.taskStore.load(params.id, context);
    if (!task) {
      throw A2AError.taskNotFound(params.id);
    }
    yield task;
    const finalStates = ["completed", "failed", "canceled", "rejected"];
    if (finalStates.includes(task.status.state)) {
      return;
    }
    const eventBus = this.eventBusManager.getByTaskId(params.id);
    if (!eventBus) {
      console.warn(`Resubscribe: No active event bus for task ${params.id}.`);
      return;
    }
    const eventQueue = new ExecutionEventQueue(eventBus);
    try {
      for await (const event of eventQueue.events()) {
        if (event.kind === "status-update" && event.taskId === params.id) {
          yield event;
        } else if (event.kind === "artifact-update" && event.taskId === params.id) {
          yield event;
        } else if (event.kind === "task" && event.id === params.id) {
          yield event;
        }
      }
    } finally {
      eventQueue.stop();
    }
  }
  async _sendPushNotificationIfNeeded(event, context) {
    if (!this.agentCard.capabilities.pushNotifications) {
      return;
    }
    let taskId = "";
    if (event.kind == "task") {
      const task2 = event;
      taskId = task2.id;
    } else {
      taskId = event.taskId;
    }
    if (!taskId) {
      console.error(`Task ID not found for event ${event.kind}.`);
      return;
    }
    const task = await this.taskStore.load(taskId, context);
    if (!task) {
      console.error(`Task ${taskId} not found.`);
      return;
    }
    this.pushNotificationSender?.send(task);
  }
  async _handleProcessingError(error, resultManager, firstResultSent, taskId, firstResultRejector) {
    if (firstResultRejector && !firstResultSent) {
      firstResultRejector(error);
      return;
    }
    if (!firstResultRejector) {
      throw error;
    }
    const currentTask = resultManager.getCurrentTask();
    const errorMessage = error instanceof Error && error.message || "Unknown error";
    if (currentTask) {
      const statusUpdateFailed = {
        taskId: currentTask.id,
        contextId: currentTask.contextId,
        status: {
          state: "failed",
          message: {
            kind: "message",
            role: "agent",
            messageId: uuidv4(),
            parts: [{ kind: "text", text: `Event processing loop failed: ${errorMessage}` }],
            taskId: currentTask.id,
            contextId: currentTask.contextId
          },
          timestamp: (/* @__PURE__ */ new Date()).toISOString()
        },
        kind: "status-update",
        final: true
      };
      try {
        await resultManager.processEvent(statusUpdateFailed);
      } catch (error2) {
        console.error(
          `Event processing loop failed for task ${taskId}: ${error2 instanceof Error && error2.message || "Unknown error"}`
        );
      }
    } else {
      console.error(`Event processing loop failed for task ${taskId}: ${errorMessage}`);
    }
  }
};

// src/server/store.ts
var InMemoryTaskStore = class {
  store = /* @__PURE__ */ new Map();
  async load(taskId) {
    const entry = this.store.get(taskId);
    return entry ? { ...entry } : void 0;
  }
  async save(task) {
    this.store.set(task.id, { ...task });
  }
};
export {
  A2AError,
  DefaultExecutionEventBus,
  DefaultExecutionEventBusManager,
  DefaultPushNotificationSender,
  DefaultRequestHandler,
  ExecutionEventQueue,
  InMemoryPushNotificationStore,
  InMemoryTaskStore,
  JsonRpcTransportHandler,
  RequestContext,
  ResultManager,
  ServerCallContext,
  UnauthenticatedUser
};
