import { scheduleRunSummarySchema } from './chunk-4HFIGLPA.js';
import { createRoute } from './chunk-PIKPS6Q6.js';
import { HTTPException } from './chunk-6QWQZI4Q.js';
import { z } from 'zod';

var signalAttributesSchema = z.record(
  z.string(),
  z.union([z.string(), z.number(), z.boolean(), z.null()]).optional()
);
var ifActiveSchema = z.object({
  behavior: z.enum(["deliver", "persist", "discard"]).optional(),
  attributes: signalAttributesSchema.optional()
});
var ifIdleSchema = z.object({
  behavior: z.enum(["wake", "persist", "discard"]).optional(),
  attributes: signalAttributesSchema.optional(),
  streamOptions: z.object({
    requestContext: z.record(z.string(), z.unknown()).optional()
  }).optional()
});
var heartbeatSchema = z.object({
  id: z.string(),
  agentId: z.string(),
  name: z.string().optional(),
  threadId: z.string().optional(),
  resourceId: z.string().optional(),
  prompt: z.string(),
  cron: z.string(),
  timezone: z.string().optional(),
  status: z.enum(["active", "paused"]),
  nextFireAt: z.number(),
  lastFireAt: z.number().optional(),
  lastRunId: z.string().optional(),
  lastRun: scheduleRunSummarySchema.optional(),
  signalType: z.string().optional(),
  tagName: z.string().optional(),
  attributes: signalAttributesSchema.optional(),
  ifActive: ifActiveSchema.optional(),
  ifIdle: ifIdleSchema.optional(),
  providerOptions: z.record(z.string(), z.unknown()).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
  createdAt: z.number(),
  updatedAt: z.number()
});
var listHeartbeatsResponseSchema = z.object({
  heartbeats: z.array(heartbeatSchema)
});
var listHeartbeatsQuerySchema = z.object({
  agentId: z.string().optional(),
  threadId: z.string().optional(),
  resourceId: z.string().optional(),
  name: z.string().optional()
});
var heartbeatPathParams = z.object({
  heartbeatId: z.string()
});
var createHeartbeatBodySchema = z.object({
  /** Optional stable id; normalized to `hb_<slug>`. A random id is generated when omitted. */
  id: z.string().optional(),
  agentId: z.string(),
  cron: z.string(),
  timezone: z.string().optional(),
  prompt: z.string(),
  name: z.string().optional(),
  threadId: z.string().optional(),
  resourceId: z.string().optional(),
  signalType: z.string().optional(),
  tagName: z.string().optional(),
  attributes: signalAttributesSchema.optional(),
  ifActive: ifActiveSchema.optional(),
  ifIdle: ifIdleSchema.optional(),
  providerOptions: z.record(z.string(), z.unknown()).optional(),
  metadata: z.record(z.string(), z.unknown()).optional()
});
var updateHeartbeatBodySchema = z.object({
  cron: z.string().optional(),
  timezone: z.string().optional(),
  prompt: z.string().optional(),
  name: z.string().optional(),
  signalType: z.string().optional(),
  tagName: z.string().optional(),
  attributes: signalAttributesSchema.optional(),
  ifActive: ifActiveSchema.optional(),
  ifIdle: ifIdleSchema.optional(),
  providerOptions: z.record(z.string(), z.unknown()).optional(),
  metadata: z.record(z.string(), z.unknown()).optional()
});
var deleteHeartbeatResponseSchema = z.object({
  message: z.string()
});
var runHeartbeatResponseSchema = z.object({
  scheduleId: z.string(),
  claimId: z.string(),
  scheduledFireAt: z.number()
});

// src/server/handlers/heartbeats.ts
function getHeartbeats(mastra) {
  const svc = mastra.heartbeats;
  if (!svc) {
    throw new HTTPException(404, { message: "Heartbeats not supported by this server" });
  }
  return svc;
}
async function loadHeartbeat(mastra, heartbeatId) {
  const heartbeats = getHeartbeats(mastra);
  const heartbeat = await heartbeats.get(heartbeatId);
  if (!heartbeat) {
    throw new HTTPException(404, { message: "Heartbeat not found" });
  }
  return heartbeat;
}
var LIST_HEARTBEATS_ROUTE = createRoute({
  method: "GET",
  path: "/heartbeats",
  responseType: "json",
  queryParamSchema: listHeartbeatsQuerySchema,
  responseSchema: listHeartbeatsResponseSchema,
  summary: "List heartbeats across all agents",
  description: "Returns the configured heartbeats, optionally filtered by agentId/threadId/resourceId/name.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, agentId, threadId, resourceId, name }) => {
    const heartbeats = getHeartbeats(mastra);
    const filter = {};
    if (agentId) filter.agentId = agentId;
    if (threadId) filter.threadId = threadId;
    if (resourceId) filter.resourceId = resourceId;
    if (name) filter.name = name;
    const rows = await heartbeats.list(filter);
    return { heartbeats: rows };
  }
});
var GET_HEARTBEAT_ROUTE = createRoute({
  method: "GET",
  path: "/heartbeats/:heartbeatId",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  responseSchema: heartbeatSchema,
  summary: "Get a heartbeat by ID",
  description: "Returns a single heartbeat by its id.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId }) => {
    return await loadHeartbeat(mastra, heartbeatId);
  }
});
var CREATE_HEARTBEAT_ROUTE = createRoute({
  method: "POST",
  path: "/heartbeats",
  responseType: "json",
  bodySchema: createHeartbeatBodySchema,
  responseSchema: heartbeatSchema,
  summary: "Create a heartbeat",
  description: "Creates a new heartbeat owned by the agent named in `agentId`. Multiple heartbeats per agent/thread are supported; each gets a random `hb_<uuid>` id. Use `name` to label distinct heartbeats on the same agent/thread.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, agentId, ...body }) => {
    try {
      mastra.getAgentById(agentId);
    } catch {
      throw new HTTPException(404, { message: `Agent "${agentId}" not found` });
    }
    const heartbeats = getHeartbeats(mastra);
    return await heartbeats.create({
      agentId,
      cron: body.cron,
      prompt: body.prompt,
      ...body.id ? { id: body.id } : {},
      ...body.name ? { name: body.name } : {},
      ...body.timezone ? { timezone: body.timezone } : {},
      ...body.threadId ? { threadId: body.threadId } : {},
      ...body.resourceId ? { resourceId: body.resourceId } : {},
      ...body.signalType ? { signalType: body.signalType } : {},
      ...body.tagName ? { tagName: body.tagName } : {},
      ...body.attributes ? { attributes: body.attributes } : {},
      ...body.ifActive ? { ifActive: body.ifActive } : {},
      ...body.ifIdle ? { ifIdle: body.ifIdle } : {},
      ...body.providerOptions ? { providerOptions: body.providerOptions } : {},
      ...body.metadata ? { metadata: body.metadata } : {}
    });
  }
});
var UPDATE_HEARTBEAT_ROUTE = createRoute({
  method: "PATCH",
  path: "/heartbeats/:heartbeatId",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  bodySchema: updateHeartbeatBodySchema,
  responseSchema: heartbeatSchema,
  summary: "Update a heartbeat",
  description: "Partial update of a heartbeat. `threadId` and `resourceId` are part of the heartbeat identity and cannot be changed \u2014 to re-target, delete and recreate. Editing `cron` (or `timezone`) recomputes `nextFireAt`.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId, ...body }) => {
    await loadHeartbeat(mastra, heartbeatId);
    const heartbeats = getHeartbeats(mastra);
    return await heartbeats.update(heartbeatId, {
      ...body.cron !== void 0 ? { cron: body.cron } : {},
      ...body.timezone !== void 0 ? { timezone: body.timezone } : {},
      ...body.prompt !== void 0 ? { prompt: body.prompt } : {},
      ...body.name !== void 0 ? { name: body.name } : {},
      ...body.signalType !== void 0 ? { signalType: body.signalType } : {},
      ...body.tagName !== void 0 ? { tagName: body.tagName } : {},
      ...body.attributes !== void 0 ? { attributes: body.attributes } : {},
      ...body.ifActive !== void 0 ? { ifActive: body.ifActive } : {},
      ...body.ifIdle !== void 0 ? { ifIdle: body.ifIdle } : {},
      ...body.providerOptions !== void 0 ? { providerOptions: body.providerOptions } : {},
      ...body.metadata !== void 0 ? { metadata: body.metadata } : {}
    });
  }
});
var DELETE_HEARTBEAT_ROUTE = createRoute({
  method: "DELETE",
  path: "/heartbeats/:heartbeatId",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  responseSchema: deleteHeartbeatResponseSchema,
  summary: "Delete a heartbeat",
  description: "Permanently deletes the heartbeat. 404 when the heartbeat does not exist.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId }) => {
    await loadHeartbeat(mastra, heartbeatId);
    const heartbeats = getHeartbeats(mastra);
    await heartbeats.delete(heartbeatId);
    return { message: "Heartbeat deleted" };
  }
});
var PAUSE_HEARTBEAT_ROUTE = createRoute({
  method: "POST",
  path: "/heartbeats/:heartbeatId/pause",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  responseSchema: heartbeatSchema,
  summary: "Pause a heartbeat",
  description: "Marks the heartbeat as paused. The scheduler tick loop will skip paused heartbeats. Idempotent.",
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId }) => {
    await loadHeartbeat(mastra, heartbeatId);
    const heartbeats = getHeartbeats(mastra);
    return await heartbeats.pause(heartbeatId);
  }
});
var RESUME_HEARTBEAT_ROUTE = createRoute({
  method: "POST",
  path: "/heartbeats/:heartbeatId/resume",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  responseSchema: heartbeatSchema,
  summary: "Resume a paused heartbeat",
  description: 'Marks the heartbeat as active and recomputes nextFireAt from "now" so a long-paused heartbeat does not fire a backlog. Idempotent.',
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId }) => {
    await loadHeartbeat(mastra, heartbeatId);
    const heartbeats = getHeartbeats(mastra);
    return await heartbeats.resume(heartbeatId);
  }
});
var RUN_HEARTBEAT_ROUTE = createRoute({
  method: "POST",
  path: "/heartbeats/:heartbeatId/run",
  responseType: "json",
  pathParamSchema: heartbeatPathParams,
  responseSchema: runHeartbeatResponseSchema,
  summary: "Fire a heartbeat now",
  description: 'Manually triggers a single heartbeat run out-of-band from the cron schedule. Records a trigger row with `triggerKind: "manual"`. Does not advance `nextFireAt`.',
  tags: ["Heartbeats"],
  requiresAuth: true,
  handler: async ({ mastra, heartbeatId }) => {
    await loadHeartbeat(mastra, heartbeatId);
    const heartbeats = getHeartbeats(mastra);
    return await heartbeats.run(heartbeatId);
  }
});

export { CREATE_HEARTBEAT_ROUTE, DELETE_HEARTBEAT_ROUTE, GET_HEARTBEAT_ROUTE, LIST_HEARTBEATS_ROUTE, PAUSE_HEARTBEAT_ROUTE, RESUME_HEARTBEAT_ROUTE, RUN_HEARTBEAT_ROUTE, UPDATE_HEARTBEAT_ROUTE };
//# sourceMappingURL=chunk-4DVFBBKV.js.map
//# sourceMappingURL=chunk-4DVFBBKV.js.map