import { responseObjectSchema, createResponseBodySchema, responseIdPathParams, deleteResponseSchema } from './chunk-6NY3T42O.js';
import { mapResponseTurnRecordToResponse, mapResponseInputToExecutionMessages, mapMastraToolsToResponseTools, createMessageId, buildCompletedResponse, buildInProgressResponse, createOutputTextPart, extractTextDelta, toResponseUsage, toResponseStatus, formatSseEvent } from './chunk-AJYJ4H7P.js';
import { findResponseTurnRecordAcrossAgents, deleteResponseTurnRecord, findResponseTurnRecord, resolveResponseTurnMessagesForStorage, getAgentMemoryStore, persistResponseTurnRecord } from './chunk-WC4RIS4D.js';
import { getAgentFromSystem } from './chunk-HOGOJPGP.js';
import { getEffectiveThreadId, getEffectiveResourceId, validateThreadOwnership } from './chunk-VLNRGJEM.js';
import { createRoute } from './chunk-2HPMUAMW.js';
import { handleError } from './chunk-P23KBWKB.js';
import { HTTPException } from './chunk-6QWQZI4Q.js';
import { __export } from './chunk-PR4QN5HX.js';
import { randomUUID } from 'crypto';

// src/server/handlers/responses.ts
var responses_exports = {};
__export(responses_exports, {
  CREATE_RESPONSE_ROUTE: () => CREATE_RESPONSE_ROUTE,
  DELETE_RESPONSE_ROUTE: () => DELETE_RESPONSE_ROUTE,
  GET_RESPONSE_ROUTE: () => GET_RESPONSE_ROUTE
});
var JSON_OBJECT_RESPONSE_SCHEMA = {
  type: "object",
  additionalProperties: true
};
function jsonResponse(data, status = 200) {
  return new Response(JSON.stringify(data), {
    status,
    headers: {
      "Content-Type": "application/json"
    }
  });
}
function createStructuredOutput(text) {
  if (!text) {
    return void 0;
  }
  switch (text.format.type) {
    case "json_object":
      return {
        schema: JSON_OBJECT_RESPONSE_SCHEMA,
        jsonPromptInjection: true
      };
    case "json_schema":
      return {
        schema: text.format.schema
      };
    default:
      return void 0;
  }
}
function getStreamedMessageOutputItem(response, responseId) {
  return response.output.find(
    (item) => item.type === "message" && item.id === responseId
  ) ?? response.output.find(
    (item) => item.type === "message"
  ) ?? null;
}
async function resolveThreadExecutionContext({
  agent,
  store,
  conversationId,
  previousResponseTurnRecord,
  requestContext
}) {
  if (conversationId && previousResponseTurnRecord && previousResponseTurnRecord.thread.id !== conversationId) {
    throw new HTTPException(400, {
      message: "conversation_id and previous_response_id must reference the same conversation thread when both are provided"
    });
  }
  if (previousResponseTurnRecord) {
    return {
      threadId: previousResponseTurnRecord.thread.id,
      resourceId: previousResponseTurnRecord.thread.resourceId
    };
  }
  const effectiveThreadId = getEffectiveThreadId(requestContext, void 0);
  const effectiveResourceId = getEffectiveResourceId(requestContext, void 0);
  if (!store && !conversationId && !effectiveThreadId) {
    return null;
  }
  const memory = await agent.getMemory({ requestContext });
  if (!memory) {
    if (conversationId) {
      throw new HTTPException(400, {
        message: "conversation_id requires the target agent to have memory configured"
      });
    }
    return null;
  }
  if (conversationId) {
    const existingThread2 = await memory.getThreadById({ threadId: conversationId });
    if (!existingThread2) {
      throw new HTTPException(404, { message: `Conversation ${conversationId} was not found` });
    }
    await validateThreadOwnership(existingThread2, effectiveResourceId);
    return {
      threadId: existingThread2.id,
      resourceId: effectiveResourceId ?? existingThread2.resourceId
    };
  }
  if (!effectiveThreadId) {
    if (!store) {
      return null;
    }
    const threadId2 = randomUUID();
    const createdThread2 = await memory.createThread({
      threadId: threadId2,
      resourceId: effectiveResourceId ?? threadId2
    });
    return {
      threadId: createdThread2.id,
      resourceId: createdThread2.resourceId
    };
  }
  const threadId = effectiveThreadId;
  const existingThread = await memory.getThreadById({ threadId });
  if (existingThread) {
    await validateThreadOwnership(existingThread, effectiveResourceId);
    return {
      threadId: existingThread.id,
      resourceId: effectiveResourceId ?? existingThread.resourceId
    };
  }
  if (!store) {
    return null;
  }
  const resourceId = effectiveResourceId ?? threadId;
  const createdThread = await memory.createThread({
    threadId,
    resourceId
  });
  return {
    threadId: createdThread.id,
    resourceId: createdThread.resourceId
  };
}
function createExecutionMemory(threadContext) {
  if (!threadContext) {
    return void 0;
  }
  return {
    memory: {
      thread: threadContext.threadId,
      resource: threadContext.resourceId
    }
  };
}
async function resolveResponseAgent({
  mastra,
  agentId
}) {
  if (!agentId) {
    throw new HTTPException(400, {
      message: "Responses requests require an agent_id"
    });
  }
  if (!mastra) {
    throw new HTTPException(500, { message: "Mastra instance is required for agent-backed responses" });
  }
  return getAgentFromSystem({ mastra, agentId });
}
async function resolveAgentMemoryStore({
  agent,
  requestContext,
  errorMessage
}) {
  const agentMemoryStore = await getAgentMemoryStore({ agent, requestContext });
  if (!agentMemoryStore) {
    throw new HTTPException(400, { message: errorMessage });
  }
  return agentMemoryStore;
}
async function executeGenerate({
  agent,
  resolvedModel,
  modelOverride,
  instructions,
  text,
  providerOptions,
  input,
  requestContext,
  abortSignal,
  threadContext
}) {
  const executionMemory = createExecutionMemory(threadContext);
  const structuredOutput = createStructuredOutput(text);
  const modelOption = modelOverride ? { model: modelOverride } : {};
  const commonOptions = {
    instructions,
    requestContext,
    abortSignal,
    ...modelOption,
    structuredOutput,
    providerOptions,
    ...executionMemory ?? {}
  };
  if (resolvedModel.specificationVersion === "v1") {
    if (threadContext) {
      return await agent.generateLegacy(input, {
        instructions,
        requestContext,
        abortSignal,
        ...modelOption,
        output: structuredOutput?.schema,
        providerOptions,
        resourceId: threadContext.resourceId,
        threadId: threadContext.threadId
      });
    }
    return await agent.generateLegacy(input, {
      instructions,
      requestContext,
      abortSignal,
      ...modelOption,
      output: structuredOutput?.schema,
      providerOptions
    });
  }
  return await agent.generate(input, commonOptions);
}
async function executeStream({
  agent,
  resolvedModel,
  modelOverride,
  instructions,
  text,
  providerOptions,
  input,
  requestContext,
  abortSignal,
  threadContext
}) {
  const executionMemory = createExecutionMemory(threadContext);
  const structuredOutput = createStructuredOutput(text);
  const modelOption = modelOverride ? { model: modelOverride } : {};
  const commonOptions = {
    instructions,
    requestContext,
    abortSignal,
    ...modelOption,
    structuredOutput,
    providerOptions,
    ...executionMemory ?? {}
  };
  if (resolvedModel.specificationVersion === "v1") {
    if (threadContext) {
      return await agent.streamLegacy(input, {
        instructions,
        requestContext,
        abortSignal,
        ...modelOption,
        output: structuredOutput?.schema,
        providerOptions,
        resourceId: threadContext.resourceId,
        threadId: threadContext.threadId
      });
    }
    return await agent.streamLegacy(input, {
      instructions,
      requestContext,
      abortSignal,
      ...modelOption,
      output: structuredOutput?.schema,
      providerOptions
    });
  }
  return await agent.stream(input, commonOptions);
}
async function resolveUsage(result) {
  return await (result.totalUsage ?? result.usage ?? null);
}
async function resolveProviderMetadata(result) {
  return await (result.providerMetadata ?? void 0);
}
async function resolveFinishReason(result) {
  return await result.finishReason ?? void 0;
}
async function resolveText(result) {
  return await result.text ?? "";
}
async function resolveCompletedResponseState(result, fallbackText) {
  const usage = await resolveUsage(result);
  return {
    completedAt: Math.floor(Date.now() / 1e3),
    status: toResponseStatus(await resolveFinishReason(result)),
    text: await resolveText(result) || fallbackText,
    usage,
    usageDetails: toResponseUsage(usage),
    providerOptions: await resolveProviderMetadata(result)
  };
}
async function storeCompletedResponse({
  agentMemoryStore,
  didStore,
  threadContext,
  responseId,
  metadata,
  completedState,
  messages
}) {
  if (!didStore || !threadContext) {
    return;
  }
  await persistResponseTurnRecord({
    memoryStore: agentMemoryStore,
    responseId,
    metadata: {
      ...metadata,
      completedAt: completedState.completedAt,
      status: completedState.status,
      usage: completedState.usageDetails,
      providerOptions: completedState.providerOptions,
      messageIds: []
    },
    threadContext,
    messages
  });
}
async function finalizeResponse({
  agentMemoryStore,
  didStore,
  threadContext,
  result,
  responseId,
  createdAt,
  model,
  instructions,
  previousResponseId,
  conversationId,
  configuredTools,
  responseMetadata,
  fallbackText
}) {
  const completedState = await resolveCompletedResponseState(result, fallbackText);
  const responseMessages = await resolveResponseTurnMessagesForStorage({
    result,
    responseId,
    text: completedState.text,
    threadContext
  });
  const response = buildCompletedResponse({
    responseId,
    outputMessageId: responseId,
    model,
    createdAt,
    completedAt: completedState.completedAt,
    status: completedState.status,
    text: completedState.text,
    usage: completedState.usage,
    instructions,
    textConfig: responseMetadata.text,
    previousResponseId,
    conversationId,
    providerOptions: completedState.providerOptions,
    tools: configuredTools,
    messages: responseMessages,
    store: didStore
  });
  await storeCompletedResponse({
    agentMemoryStore,
    didStore,
    threadContext,
    responseId,
    metadata: responseMetadata,
    completedState,
    messages: responseMessages
  });
  return { completedState, response, responseMessages };
}
async function prepareCreateResponseRequest({
  body,
  mastra,
  requestContext
}) {
  const executionInput = mapResponseInputToExecutionMessages(body.input);
  const agent = await resolveResponseAgent({
    mastra,
    agentId: body.agent_id
  });
  const resolvedModel = await agent.getModel({
    requestContext,
    modelConfig: body.model
  });
  const responseModel = body.model ?? (() => {
    if (resolvedModel.provider && resolvedModel.modelId) {
      const publicProviderId = resolvedModel.provider.includes(".") ? resolvedModel.provider.split(".")[0] : resolvedModel.provider;
      return `${publicProviderId}/${resolvedModel.modelId}`;
    }
    if (resolvedModel.modelId) {
      return resolvedModel.modelId;
    }
    throw new HTTPException(500, {
      message: "Responses route could not determine the effective model for this request"
    });
  })();
  const shouldStore = body.store ?? false;
  const needsMemoryStore = shouldStore || Boolean(body.conversation_id) || Boolean(body.previous_response_id);
  const agentMemoryStore = needsMemoryStore ? await resolveAgentMemoryStore({
    agent,
    requestContext,
    errorMessage: body.previous_response_id ? "previous_response_id requires the target agent to have memory storage configured" : shouldStore ? "Stored responses require the target agent to have memory storage configured" : "conversation_id requires the target agent to have memory storage configured"
  }) : null;
  const previousResponseTurnRecord = body.previous_response_id ? await findResponseTurnRecord({ agent, responseId: body.previous_response_id, requestContext }) : null;
  if (body.previous_response_id && !previousResponseTurnRecord) {
    throw new HTTPException(404, { message: `Stored response ${body.previous_response_id} was not found` });
  }
  const configuredTools = mapMastraToolsToResponseTools(
    await Promise.resolve(agent.listTools({ requestContext }))
  );
  const responseId = createMessageId();
  const createdAt = Math.floor(Date.now() / 1e3);
  const threadContext = await resolveThreadExecutionContext({
    agent,
    store: shouldStore,
    conversationId: body.conversation_id,
    previousResponseTurnRecord,
    requestContext
  });
  if (shouldStore && !threadContext) {
    throw new HTTPException(400, {
      message: "Stored responses require the target agent to have memory configured"
    });
  }
  const didStore = shouldStore && Boolean(threadContext);
  return {
    agent,
    agentMemoryStore,
    configuredTools,
    createdAt,
    didStore,
    executionInput,
    previousResponseTurnRecord,
    resolvedModel,
    responseId,
    responseModel,
    responseMetadata: {
      agentId: agent.id,
      model: responseModel,
      createdAt,
      instructions: body.instructions,
      text: body.text,
      previousResponseId: previousResponseTurnRecord?.message.id ?? body.previous_response_id,
      tools: configuredTools,
      store: didStore
    },
    threadContext
  };
}
function createResponseEventStream({
  agentMemoryStore,
  body,
  configuredTools,
  createdAt,
  didStore,
  previousResponseTurnRecord,
  responseId,
  responseModel,
  responseMetadata,
  streamResult,
  threadContext
}) {
  const createdResponse = buildInProgressResponse({
    responseId,
    model: responseModel,
    createdAt,
    instructions: body.instructions,
    textConfig: body.text,
    previousResponseId: body.previous_response_id,
    conversationId: threadContext?.threadId ?? body.conversation_id,
    tools: configuredTools,
    store: didStore
  });
  return new ReadableStream({
    async start(controller) {
      let sequenceNumber = 1;
      const enqueueEvent = (eventName, payload) => {
        controller.enqueue(
          formatSseEvent(eventName, {
            ...payload,
            sequence_number: sequenceNumber++
          })
        );
      };
      enqueueEvent("response.created", {
        type: "response.created",
        response: createdResponse
      });
      enqueueEvent("response.in_progress", {
        type: "response.in_progress",
        response: createdResponse
      });
      enqueueEvent("response.output_item.added", {
        type: "response.output_item.added",
        output_index: 0,
        item: {
          id: responseId,
          type: "message",
          role: "assistant",
          status: "in_progress",
          content: []
        }
      });
      enqueueEvent("response.content_part.added", {
        type: "response.content_part.added",
        output_index: 0,
        content_index: 0,
        item_id: responseId,
        part: createOutputTextPart("")
      });
      let text = "";
      const fullStream = await streamResult.fullStream;
      const reader = fullStream.getReader();
      try {
        while (true) {
          const { done, value } = await reader.read();
          if (done) {
            break;
          }
          const delta = extractTextDelta(value);
          if (delta) {
            text += delta;
            enqueueEvent("response.output_text.delta", {
              type: "response.output_text.delta",
              output_index: 0,
              content_index: 0,
              item_id: responseId,
              delta
            });
          }
        }
        const { completedState, response } = await finalizeResponse({
          agentMemoryStore,
          didStore,
          threadContext,
          result: streamResult,
          responseId,
          createdAt,
          model: responseModel,
          instructions: body.instructions,
          previousResponseId: previousResponseTurnRecord?.message.id ?? body.previous_response_id,
          conversationId: threadContext?.threadId ?? body.conversation_id,
          configuredTools,
          responseMetadata,
          fallbackText: text
        });
        enqueueEvent("response.output_text.done", {
          type: "response.output_text.done",
          output_index: 0,
          content_index: 0,
          item_id: responseId,
          text: completedState.text
        });
        const completedItem = getStreamedMessageOutputItem(response, responseId) ?? {
          id: responseId,
          type: "message",
          role: "assistant",
          status: "completed",
          content: [createOutputTextPart(completedState.text)]
        };
        enqueueEvent("response.content_part.done", {
          type: "response.content_part.done",
          output_index: 0,
          content_index: 0,
          item_id: responseId,
          part: createOutputTextPart(completedState.text)
        });
        enqueueEvent("response.output_item.done", {
          type: "response.output_item.done",
          output_index: 0,
          item: completedItem
        });
        enqueueEvent("response.completed", {
          type: "response.completed",
          response
        });
        controller.close();
      } catch (error) {
        controller.error(error);
      } finally {
        reader.releaseLock();
      }
    }
  });
}
var CREATE_RESPONSE_ROUTE = createRoute({
  method: "POST",
  path: "/v1/responses",
  responseType: "datastream-response",
  bodySchema: createResponseBodySchema,
  responseSchema: responseObjectSchema,
  summary: "Create a response",
  description: "Creates a response through a Mastra-hosted Responses API-compatible route",
  tags: ["Responses"],
  requiresAuth: true,
  requiresPermission: "agents:execute",
  handler: async ({ mastra, requestContext, abortSignal, ...body }) => {
    try {
      const {
        agent,
        agentMemoryStore,
        configuredTools,
        createdAt,
        didStore,
        executionInput,
        previousResponseTurnRecord,
        resolvedModel,
        responseId,
        responseModel,
        responseMetadata,
        threadContext
      } = await prepareCreateResponseRequest({ body, mastra, requestContext });
      if (!body.stream) {
        const result = await executeGenerate({
          agent,
          resolvedModel,
          modelOverride: body.model,
          instructions: body.instructions,
          text: body.text,
          providerOptions: body.providerOptions,
          input: executionInput,
          requestContext,
          abortSignal,
          threadContext
        });
        const { response } = await finalizeResponse({
          agentMemoryStore,
          didStore,
          threadContext,
          result,
          responseId,
          createdAt,
          model: responseModel,
          instructions: body.instructions,
          previousResponseId: previousResponseTurnRecord?.message.id ?? body.previous_response_id,
          conversationId: threadContext?.threadId ?? body.conversation_id,
          configuredTools,
          responseMetadata,
          fallbackText: ""
        });
        return jsonResponse(response);
      }
      const streamResult = await executeStream({
        agent,
        resolvedModel,
        modelOverride: body.model,
        instructions: body.instructions,
        text: body.text,
        providerOptions: body.providerOptions,
        input: executionInput,
        requestContext,
        abortSignal,
        threadContext
      });
      const stream = createResponseEventStream({
        agentMemoryStore,
        body,
        configuredTools,
        createdAt,
        didStore,
        previousResponseTurnRecord,
        responseId,
        responseModel,
        responseMetadata,
        streamResult,
        threadContext
      });
      return new Response(stream, {
        headers: {
          "Content-Type": "text/event-stream; charset=utf-8",
          "Cache-Control": "no-cache",
          Connection: "keep-alive",
          "X-Accel-Buffering": "no"
        }
      });
    } catch (error) {
      return handleError(error, "Error creating response");
    }
  }
});
var GET_RESPONSE_ROUTE = createRoute({
  method: "GET",
  path: "/v1/responses/:responseId",
  responseType: "json",
  pathParamSchema: responseIdPathParams,
  responseSchema: responseObjectSchema,
  summary: "Retrieve a stored response",
  description: "Returns a previously stored response object",
  tags: ["Responses"],
  requiresAuth: true,
  requiresPermission: "agents:read",
  handler: async ({ mastra, requestContext, responseId }) => {
    try {
      const responseTurnRecord = await findResponseTurnRecordAcrossAgents({ mastra, responseId, requestContext });
      if (!responseTurnRecord) {
        throw new HTTPException(404, { message: `Stored response ${responseId} was not found` });
      }
      return mapResponseTurnRecordToResponse(responseTurnRecord);
    } catch (error) {
      return handleError(error, "Error retrieving response");
    }
  }
});
var DELETE_RESPONSE_ROUTE = createRoute({
  method: "DELETE",
  path: "/v1/responses/:responseId",
  responseType: "json",
  pathParamSchema: responseIdPathParams,
  responseSchema: deleteResponseSchema,
  summary: "Delete a stored response",
  description: "Deletes a stored response so it can no longer be retrieved or chained",
  tags: ["Responses"],
  requiresAuth: true,
  requiresPermission: "agents:delete",
  handler: async ({ mastra, requestContext, responseId }) => {
    try {
      const responseTurnRecord = await findResponseTurnRecordAcrossAgents({ mastra, responseId, requestContext });
      if (!responseTurnRecord) {
        throw new HTTPException(404, { message: `Stored response ${responseId} was not found` });
      }
      await deleteResponseTurnRecord({ responseTurnRecord });
      const response = {
        id: responseId,
        object: "response",
        deleted: true
      };
      return response;
    } catch (error) {
      return handleError(error, "Error deleting response");
    }
  }
});

export { CREATE_RESPONSE_ROUTE, DELETE_RESPONSE_ROUTE, GET_RESPONSE_ROUTE, responses_exports };
//# sourceMappingURL=chunk-76DAOWXY.js.map
//# sourceMappingURL=chunk-76DAOWXY.js.map