'use strict';

var chunkKXXILK3T_cjs = require('./chunk-KXXILK3T.cjs');
var chunkSTHQS3QR_cjs = require('./chunk-STHQS3QR.cjs');
var chunkEFX5WYRT_cjs = require('./chunk-EFX5WYRT.cjs');
var chunk6P7P7Y5U_cjs = require('./chunk-6P7P7Y5U.cjs');
var chunkO7I5CWRX_cjs = require('./chunk-O7I5CWRX.cjs');
var a2a = require('@mastra/core/a2a');
var zod = require('zod');

// src/server/handlers/a2a.ts
var a2a_exports = {};
chunkO7I5CWRX_cjs.__export(a2a_exports, {
  AGENT_EXECUTION_ROUTE: () => AGENT_EXECUTION_ROUTE,
  GET_AGENT_CARD_ROUTE: () => GET_AGENT_CARD_ROUTE,
  getAgentCardByIdHandler: () => getAgentCardByIdHandler,
  getAgentExecutionHandler: () => getAgentExecutionHandler,
  handleMessageSend: () => handleMessageSend,
  handleMessageStream: () => handleMessageStream,
  handleTaskCancel: () => handleTaskCancel,
  handleTaskGet: () => handleTaskGet
});
function normalizeError(error, reqId, taskId, logger) {
  let a2aError;
  if (error instanceof a2a.MastraA2AError) {
    a2aError = error;
  } else if (error instanceof Error) {
    a2aError = a2a.MastraA2AError.internalError(error.message, { stack: error.stack });
  } else {
    a2aError = a2a.MastraA2AError.internalError("An unknown error occurred.", error);
  }
  if (taskId && !a2aError.taskId) {
    a2aError.taskId = taskId;
  }
  logger?.error(`Error processing request (Task: ${a2aError.taskId ?? "N/A"}, ReqID: ${reqId ?? "N/A"}):`, a2aError);
  return createErrorResponse(reqId, a2aError.toJSONRPCError());
}
function createErrorResponse(id, error) {
  return {
    jsonrpc: "2.0",
    id,
    // Can be null if request ID was invalid/missing
    error
  };
}
function createSuccessResponse(id, result) {
  if (!id) {
    throw a2a.MastraA2AError.internalError("Cannot create success response for null ID.");
  }
  return {
    jsonrpc: "2.0",
    id,
    result
  };
}
function convertToCoreMessage(message) {
  return {
    role: message.role === "user" ? "user" : "assistant",
    content: message.parts.map((msg) => convertToCoreMessagePart(msg))
  };
}
function convertToCoreMessagePart(part) {
  switch (part.kind) {
    case "text":
      return {
        type: "text",
        text: part.text
      };
    case "file":
      return {
        type: "file",
        data: "uri" in part.file ? new URL(part.file.uri) : part.file.bytes,
        mimeType: part.file.mimeType
      };
    case "data":
      throw new Error("Data parts are not supported in core messages");
  }
}

// src/server/a2a/tasks.ts
function isTaskStatusUpdate(update) {
  return "state" in update && !("parts" in update);
}
function isArtifactUpdate(update) {
  return "kind" in update && update.kind === "artifact-update";
}
function applyUpdateToTask(current, update) {
  let newTask = structuredClone(current);
  if (isTaskStatusUpdate(update)) {
    newTask.status = {
      ...newTask.status,
      // Keep existing properties if not overwritten
      ...update,
      // Apply updates
      timestamp: (/* @__PURE__ */ new Date()).toISOString()
    };
  } else if (isArtifactUpdate(update)) {
    if (!newTask.artifacts) {
      newTask.artifacts = [];
    } else {
      newTask.artifacts = [...newTask.artifacts];
    }
    const artifact = update.artifact;
    const existingIndex = newTask.artifacts.findIndex((a) => a.name === artifact.name);
    const existingArtifact = newTask.artifacts[existingIndex];
    if (existingArtifact) {
      if (update.append) {
        const appendedArtifact = JSON.parse(JSON.stringify(existingArtifact));
        appendedArtifact.parts.push(...artifact.parts);
        if (artifact.metadata) {
          appendedArtifact.metadata = {
            ...appendedArtifact.metadata || {},
            ...artifact.metadata
          };
        }
        if (artifact.description) appendedArtifact.description = artifact.description;
        newTask.artifacts[existingIndex] = appendedArtifact;
      } else {
        newTask.artifacts[existingIndex] = { ...artifact };
      }
    } else {
      newTask.artifacts.push({ ...artifact });
    }
  }
  return newTask;
}
async function loadOrCreateTask({
  agentId,
  taskId,
  taskStore,
  message,
  contextId,
  metadata,
  logger
}) {
  const data = await taskStore.load({ agentId, taskId });
  if (!data) {
    const initialTask = {
      id: taskId,
      contextId: contextId || crypto.randomUUID(),
      status: {
        state: "submitted",
        timestamp: (/* @__PURE__ */ new Date()).toISOString(),
        message: void 0
      },
      artifacts: [],
      history: [message],
      metadata,
      kind: "task"
    };
    logger?.info(`[Task ${taskId}] Created new task.`);
    await taskStore.save({ agentId, data: initialTask });
    return initialTask;
  }
  logger?.info(`[Task ${taskId}] Loaded existing task.`);
  let updatedData = data;
  updatedData.history = [...data.history || [], message];
  const { status } = data;
  const finalStates = ["completed", "failed", "canceled"];
  if (finalStates.includes(status.state)) {
    logger?.warn(`[Task ${taskId}] Received message for task in final state ${status.state}. Restarting.`);
    updatedData = applyUpdateToTask(updatedData, {
      state: "submitted",
      message: void 0
    });
  } else if (status.state === "input-required") {
    logger?.info(`[Task ${taskId}] Changing state from 'input-required' to 'working'.`);
    updatedData = applyUpdateToTask(updatedData, { state: "working" });
  } else if (status.state === "working") {
    logger?.warn(`[Task ${taskId}] Received message while already 'working'. Proceeding.`);
  }
  await taskStore.save({ agentId, data: updatedData });
  return updatedData;
}
function createTaskContext({
  task,
  userMessage,
  history,
  activeCancellations
}) {
  return {
    task: structuredClone(task),
    userMessage,
    history: structuredClone(history),
    isCancelled: () => activeCancellations.has(task.id)
  };
}

// src/server/handlers/a2a.ts
var messageSendParamsSchema = zod.z.object({
  message: zod.z.object({
    role: zod.z.enum(["user", "agent"]),
    parts: zod.z.array(
      zod.z.object({
        kind: zod.z.enum(["text"]),
        text: zod.z.string()
      })
    ),
    kind: zod.z.literal("message"),
    messageId: zod.z.string(),
    contextId: zod.z.string().optional(),
    taskId: zod.z.string().optional(),
    referenceTaskIds: zod.z.array(zod.z.string()).optional(),
    extensions: zod.z.array(zod.z.string()).optional(),
    metadata: zod.z.record(zod.z.string(), zod.z.any()).optional()
  })
});
async function getAgentCardByIdHandler({
  mastra,
  agentId,
  executionUrl = `/a2a/${agentId}`,
  provider = {
    organization: "Mastra",
    url: "https://mastra.ai"
  },
  version = "1.0",
  requestContext
}) {
  const agent = await chunkSTHQS3QR_cjs.getAgentFromSystem({ mastra, agentId });
  const [instructions, tools] = await Promise.all([agent.getInstructions({ requestContext }), agent.listTools({ requestContext })]);
  const agentCard = {
    name: agent.id || agentId,
    description: chunkEFX5WYRT_cjs.convertInstructionsToString(instructions),
    url: executionUrl,
    provider,
    version,
    capabilities: {
      streaming: true,
      // All agents support streaming
      pushNotifications: false,
      stateTransitionHistory: false
    },
    defaultInputModes: ["text"],
    defaultOutputModes: ["text"],
    // Convert agent tools to skills format for A2A protocol
    skills: Object.entries(tools).map(([toolId, tool]) => ({
      id: toolId,
      name: toolId,
      description: tool.description || `Tool: ${toolId}`,
      // Optional fields
      tags: ["tool"]
    }))
  };
  return agentCard;
}
function validateMessageSendParams(params) {
  try {
    messageSendParamsSchema.parse(params);
  } catch (error) {
    if (error instanceof zod.z.ZodError) {
      throw a2a.MastraA2AError.invalidParams(error.issues[0].message);
    }
    throw error;
  }
}
async function handleMessageSend({
  requestId,
  params,
  taskStore,
  agent,
  agentId,
  logger,
  requestContext
}) {
  validateMessageSendParams(params);
  const { message, metadata } = params;
  const { contextId } = message;
  const taskId = message.taskId || crypto.randomUUID();
  let currentData = await loadOrCreateTask({
    taskId,
    taskStore,
    agentId,
    message,
    contextId,
    metadata
  });
  createTaskContext({
    task: currentData,
    userMessage: message,
    history: currentData.history || [],
    activeCancellations: taskStore.activeCancellations
  });
  try {
    const resourceId = metadata?.resourceId ?? message.metadata?.resourceId ?? agentId;
    const result = await agent.generate([convertToCoreMessage(message)], {
      runId: taskId,
      requestContext,
      ...contextId ? { threadId: contextId, resourceId } : {}
    });
    currentData = applyUpdateToTask(currentData, {
      state: "completed",
      message: {
        messageId: crypto.randomUUID(),
        role: "agent",
        parts: [
          {
            kind: "text",
            text: result.text
          }
        ],
        kind: "message"
      }
    });
    currentData.metadata = {
      ...currentData.metadata,
      execution: {
        toolCalls: result.toolCalls,
        toolResults: result.toolResults,
        usage: result.usage,
        finishReason: result.finishReason
      }
    };
    await taskStore.save({ agentId, data: currentData });
  } catch (handlerError) {
    const failureStatusUpdate = {
      state: "failed",
      message: {
        messageId: crypto.randomUUID(),
        role: "agent",
        parts: [
          {
            kind: "text",
            text: `Handler failed: ${handlerError instanceof Error ? handlerError.message : String(handlerError)}`
          }
        ],
        kind: "message"
      }
    };
    currentData = applyUpdateToTask(currentData, failureStatusUpdate);
    try {
      await taskStore.save({ agentId, data: currentData });
    } catch (saveError) {
      logger?.error(`Failed to save task ${currentData.id} after handler error:`, saveError?.message);
    }
    return normalizeError(handlerError, requestId, currentData.id, logger);
  }
  return createSuccessResponse(requestId, currentData);
}
async function handleTaskGet({
  requestId,
  taskStore,
  agentId,
  taskId
}) {
  const task = await taskStore.load({ agentId, taskId });
  if (!task) {
    throw a2a.MastraA2AError.taskNotFound(taskId);
  }
  return createSuccessResponse(requestId, task);
}
async function* handleMessageStream({
  requestId,
  params,
  taskStore,
  agent,
  agentId,
  logger,
  requestContext
}) {
  yield createSuccessResponse(requestId, {
    state: "working",
    message: {
      messageId: crypto.randomUUID(),
      kind: "message",
      role: "agent",
      parts: [{ kind: "text", text: "Generating response..." }]
    }
  });
  let result;
  try {
    result = await handleMessageSend({
      requestId,
      params,
      taskStore,
      agent,
      agentId,
      requestContext,
      logger
    });
  } catch (err) {
    if (!(err instanceof a2a.MastraA2AError)) {
      throw err;
    }
    result = createErrorResponse(requestId, err.toJSONRPCError());
  }
  yield result;
}
async function handleTaskCancel({
  requestId,
  taskStore,
  agentId,
  taskId,
  logger
}) {
  let data = await taskStore.load({
    agentId,
    taskId
  });
  if (!data) {
    throw a2a.MastraA2AError.taskNotFound(taskId);
  }
  const finalStates = ["completed", "failed", "canceled"];
  if (finalStates.includes(data.status.state)) {
    logger?.info(`Task ${taskId} already in final state ${data.status.state}, cannot cancel.`);
    return createSuccessResponse(requestId, data);
  }
  taskStore.activeCancellations.add(taskId);
  const cancelUpdate = {
    state: "canceled",
    message: {
      role: "agent",
      parts: [{ kind: "text", text: "Task cancelled by request." }],
      kind: "message",
      messageId: crypto.randomUUID()
    }
  };
  data = applyUpdateToTask(data, cancelUpdate);
  await taskStore.save({ agentId, data });
  taskStore.activeCancellations.delete(taskId);
  return createSuccessResponse(requestId, data);
}
async function getAgentExecutionHandler({
  requestId,
  mastra,
  agentId,
  requestContext,
  method,
  params,
  taskStore,
  logger
}) {
  const agent = await chunkSTHQS3QR_cjs.getAgentFromSystem({ mastra, agentId });
  let taskId;
  try {
    taskId = "id" in params ? params.id : params.message?.taskId || "No task ID provided";
    switch (method) {
      case "message/send": {
        const result2 = await handleMessageSend({
          requestId,
          params,
          taskStore,
          agent,
          agentId,
          requestContext
        });
        return result2;
      }
      case "message/stream":
        const result = await handleMessageStream({
          requestId,
          taskStore,
          params,
          agent,
          agentId,
          requestContext
        });
        return result;
      case "tasks/get": {
        const result2 = await handleTaskGet({
          requestId,
          taskStore,
          agentId,
          taskId
        });
        return result2;
      }
      case "tasks/cancel": {
        const result2 = await handleTaskCancel({
          requestId,
          taskStore,
          agentId,
          taskId
        });
        return result2;
      }
      default:
        throw a2a.MastraA2AError.methodNotFound(method);
    }
  } catch (error) {
    if (error instanceof a2a.MastraA2AError && taskId && !error.taskId) {
      error.taskId = taskId;
    }
    return normalizeError(error, requestId, taskId, logger);
  }
}
var GET_AGENT_CARD_ROUTE = chunk6P7P7Y5U_cjs.createRoute({
  method: "GET",
  path: "/.well-known/:agentId/agent-card.json",
  responseType: "json",
  pathParamSchema: chunkKXXILK3T_cjs.a2aAgentIdPathParams,
  responseSchema: chunkKXXILK3T_cjs.agentCardResponseSchema,
  summary: "Get agent card",
  description: "Returns the agent card information for A2A protocol discovery",
  tags: ["Agent-to-Agent"],
  requiresAuth: true,
  handler: async ({ mastra, agentId, requestContext }) => {
    const executionUrl = `/a2a/${agentId}`;
    const provider = {
      organization: "Mastra",
      url: "https://mastra.ai"
    };
    const version = "1.0";
    const agent = await chunkSTHQS3QR_cjs.getAgentFromSystem({ mastra, agentId });
    const [instructions, tools] = await Promise.all([agent.getInstructions({ requestContext }), agent.listTools({ requestContext })]);
    const agentCard = {
      name: agent.id || agentId,
      description: chunkEFX5WYRT_cjs.convertInstructionsToString(instructions),
      url: executionUrl,
      provider,
      version,
      capabilities: {
        streaming: true,
        pushNotifications: false,
        stateTransitionHistory: false
      },
      defaultInputModes: ["text"],
      defaultOutputModes: ["text"],
      skills: Object.entries(tools).map(([toolId, tool]) => ({
        id: toolId,
        name: toolId,
        description: tool.description || `Tool: ${toolId}`,
        tags: ["tool"]
      }))
    };
    return agentCard;
  }
});
var AGENT_EXECUTION_ROUTE = chunk6P7P7Y5U_cjs.createRoute({
  method: "POST",
  path: "/a2a/:agentId",
  responseType: "json",
  pathParamSchema: chunkKXXILK3T_cjs.a2aAgentIdPathParams,
  bodySchema: chunkKXXILK3T_cjs.agentExecutionBodySchema,
  responseSchema: chunkKXXILK3T_cjs.agentExecutionResponseSchema,
  summary: "Execute agent",
  description: "Executes an agent action via JSON-RPC 2.0 over A2A protocol",
  tags: ["Agent-to-Agent"],
  requiresAuth: true,
  handler: async ({ mastra, agentId, requestContext, taskStore, ...bodyParams }) => {
    const { id: requestId, method, params } = bodyParams;
    return await getAgentExecutionHandler({
      requestId: String(requestId),
      mastra,
      agentId,
      requestContext,
      method,
      params,
      taskStore
    });
  }
});

exports.AGENT_EXECUTION_ROUTE = AGENT_EXECUTION_ROUTE;
exports.GET_AGENT_CARD_ROUTE = GET_AGENT_CARD_ROUTE;
exports.a2a_exports = a2a_exports;
exports.getAgentCardByIdHandler = getAgentCardByIdHandler;
exports.getAgentExecutionHandler = getAgentExecutionHandler;
exports.handleMessageSend = handleMessageSend;
exports.handleMessageStream = handleMessageStream;
exports.handleTaskCancel = handleTaskCancel;
exports.handleTaskGet = handleTaskGet;
//# sourceMappingURL=chunk-F4HPG2WH.cjs.map
//# sourceMappingURL=chunk-F4HPG2WH.cjs.map