import { a as attr_class, e as ensure_array_like, c as bind_props } from './index2-CzosXNJA.js';
import { Y as fallback, X as escape_html } from './context-BZ_07CFR.js';
import { h as html } from './html-FW6Ia4bL.js';
import { z } from 'zod';

class MockGenerator {
  poolSize = 120;
  // ----- CALLS -----
  async fetchCalls(limit, phoneFilter, lastCallId) {
    await delay(150);
    return this.generateCalls(limit, phoneFilter, lastCallId);
  }
  generateCalls(limit, phoneFilter, lastCallId) {
    const now = Date.now();
    const items = [];
    for (let i = 0; i < this.poolSize; i++) {
      const id = String(1e5 + i);
      items.push({
        callId: id,
        phoneNumber: `+44 7700 ${String(1e3 + i % 90).padStart(4, "0")}`,
        duration: Math.floor(Math.random() * 600),
        audioUrl: `https://cdn.example.com/audio/${id}.mp3`,
        transcript: JSON.stringify({
          text: "Manager: Thank you for calling DHL, you're speaking to Sophie. Am I speaking with um Anna Williams?    User: Yes Manager: Lovely to chat with you, Anna! How can I help you today?    User: We’ll need help assembling the bed, I forgot to include that in the list. Manager: Ah, I see. No worries at all. You can actually use our self-service tool online to add that dismantling and reassembly service to your booking. It's really handy and updates instantly. I'll send you a WhatsApp message with a link to it, alright? If anything's a bit tricky, just let us know, and we'll sort it out for you. Does that sound good?    User: Oh, okay Manager: Great! I'll send you that link shortly. If you run into any issues or have more questions, just give us a ring, and we'll sort it out together. Anything else I can help with right now?    User: No, thank you! Manager: Alright, Anna. Have a lovely day, and do reach out if you need anything else. Cheers!",
          words: []
        }),
        createdAt: now - i * 36e5
      });
    }
    let filtered = items;
    if (phoneFilter) {
      const q = phoneFilter.replace(/\s+/g, "");
      filtered = items.filter((it) => it.phoneNumber?.replace(/\s+/g, "").includes(q));
    }
    filtered.sort((a, b) => b.createdAt - a.createdAt);
    if (lastCallId) {
      const idx = filtered.findIndex((it) => it.callId === lastCallId);
      if (idx >= 0) filtered = filtered.slice(idx + 1);
    }
    const pageItems = filtered.slice(0, limit);
    const nextlastCallId = pageItems.length ? pageItems[pageItems.length - 1].callId : void 0;
    return { limit, items: pageItems, lastCallId: nextlastCallId };
  }
  // ----- STEP TRACES -----
  async fetchStepTraces(callId) {
    await delay(150);
    return this.generateTraces(callId);
  }
  generateTraces(callId) {
    const rng = mulberry32(hashString(callId));
    const count = Math.floor(rng() * 5) + 3;
    const now = Date.now();
    const traces = Array.from({ length: count }, (_, i) => {
      const ts = now - (count - i) * 3e4;
      return {
        traceId: `trace-${callId}-${i}`,
        callId,
        scopeId: `scope-${i}`,
        workflowId: `workflow-${i}`,
        workflowRunId: `run-${callId}-${i}`,
        renderedPrompt: `Rendered prompt for ${callId}/${i}`,
        receivedContext: JSON.stringify({ foo: "bar" }, null, 2),
        receivedPrompt: `User says #${i}`,
        createdAt: ts,
        stringifiedConversation: JSON.stringify([{ role: "user", text: "hi" }], null, 2),
        response: `response ${i}`,
        model: "gpt-4"
      };
    });
    traces.sort((a, b) => b.createdAt - a.createdAt);
    return traces;
  }
}
function delay(ms) {
  return new Promise((r) => setTimeout(r, ms));
}
function hashString(s) {
  let h = 1779033703 ^ s.length;
  for (let i = 0; i < s.length; i++) {
    h = Math.imul(h ^ s.charCodeAt(i), 3432918353);
    h = h << 13 | h >>> 19;
  }
  return h >>> 0;
}
function mulberry32(seed) {
  return function() {
    let t = seed += 1831565813;
    t = Math.imul(t ^ t >>> 15, t | 1);
    t ^= t + Math.imul(t ^ t >>> 7, t | 61);
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  };
}
const mockGenerator = new MockGenerator();
function CollapseExpand($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let value = fallback($$props["value"], "");
    let limit = fallback($$props["limit"], 200);
    let maxLines = fallback($$props["maxLines"], null);
    let className = fallback($$props["className"], "");
    let expandedLabel = fallback($$props["expandedLabel"], "collapse");
    let collapsedLabel = fallback($$props["collapsedLabel"], "...more");
    let initiallyExpanded = fallback($$props["initiallyExpanded"], false);
    let stopPropagation = fallback($$props["stopPropagation"], true);
    let expanded = fallback($$props["expanded"], initiallyExpanded);
    let treatPlainText = fallback($$props["treatPlainText"], false);
    let highlightPrompt = fallback($$props["highlightPrompt"], false);
    function escapeHtml(text) {
      return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    }
    function highlightPromptText(raw) {
      const s = normalizeNewlines(raw);
      let html2 = escapeHtml(s);
      const curlyBlocks = [];
      html2 = html2.replace(/(\{+[\s\S]*?\}+)/g, (match) => {
        const id = curlyBlocks.length;
        curlyBlocks.push(match);
        return `__CURLY${id}__`;
      });
      html2 = html2.replace(/^(\s*#.*)$/gm, '<span class="prompt-heading">$1</span>');
      html2 = html2.replace(/(&lt;[^&]*?&gt;)/g, '<span class="mtk8">$1</span>');
      html2 = html2.replace(/^(\s*)(\d+)([.)])(\s+)/gm, (_match, p1, p2, p3, p4) => `${p1}<span class="mtk8">${p2}${p3}</span>${p4}`);
      curlyBlocks.forEach((block, idx) => {
        const highlighted = `<span class="mtk5">${block}</span>`;
        html2 = html2.replace(`__CURLY${idx}__`, highlighted);
      });
      html2 = html2.replace(/\n/g, "<br/>");
      return html2;
    }
    function normalizeNewlines(s) {
      let result = s.replace(/\r\n/g, "\n");
      result = result.replace(/\\n/g, "\n");
      return result;
    }
    function getPlain(v) {
      try {
        if (Array.isArray(v)) {
          const s = v.map((s2) => s2?.text ?? s2?.content ?? JSON.stringify(s2)).join(" ");
          return normalizeNewlines(s);
        }
        if (typeof v === "string") {
          try {
            const parsed = JSON.parse(v);
            if (Array.isArray(parsed)) {
              const s = parsed.map((s2) => s2?.text ?? s2?.content ?? JSON.stringify(s2)).join(" ");
              return normalizeNewlines(s);
            }
            return normalizeNewlines(v);
          } catch {
            return normalizeNewlines(v);
          }
        }
        return normalizeNewlines(JSON.stringify(v));
      } catch {
        return normalizeNewlines(String(v ?? ""));
      }
    }
    function getFull(v) {
      try {
        if (Array.isArray(v)) {
          const s = v.map((s2) => s2?.text ?? s2?.content ?? JSON.stringify(s2)).join("\n");
          return normalizeNewlines(s);
        }
        if (typeof v === "string") {
          try {
            const parsed = JSON.parse(v);
            if (Array.isArray(parsed)) {
              const s = parsed.map((s2) => s2?.text ?? s2?.content ?? JSON.stringify(s2)).join("\n");
              return normalizeNewlines(s);
            }
            return normalizeNewlines(v);
          } catch {
            return normalizeNewlines(v);
          }
        }
        return normalizeNewlines(JSON.stringify(v, null, 2));
      } catch {
        return normalizeNewlines(String(v ?? ""));
      }
    }
    function parseLine(raw) {
      const s = normalizeNewlines(raw);
      const lines = s.split(/\n+/).map((l) => l.trim()).filter((l) => l.length > 0);
      const segments2 = [];
      let currentRole = void 0;
      let currentText = "";
      for (const line of lines) {
        const m = line.match(/^(user|assistant|system|customer|caller|tool|model|agent)\s*[:\-]\s*(.*)$/i);
        if (m) {
          if (currentText) {
            segments2.push({ text: currentText, role: currentRole });
          }
          currentRole = m[1].toLowerCase();
          currentText = m[2] ?? "";
        } else {
          if (currentText) {
            currentText += "\n" + line;
          } else {
            currentText = line;
          }
        }
      }
      if (currentText) {
        segments2.push({ text: currentText, role: currentRole });
      }
      return segments2;
    }
    function asSegments(v) {
      try {
        let raw = v;
        if (typeof v === "string") {
          try {
            raw = JSON.parse(v);
          } catch {
            if (!treatPlainText) return [];
            return parseLine(v);
          }
        }
        if (!Array.isArray(raw)) {
          if (Array.isArray(raw?.messages)) {
            raw = raw.messages;
          } else {
            return [];
          }
        }
        return raw.map((s) => {
          let text;
          if (s?.text != null) {
            text = String(s.text);
          } else if (s?.content != null) {
            if (Array.isArray(s.content)) {
              text = s.content.map((part) => {
                if (typeof part === "string") return part;
                if (typeof part?.text === "string") return part.text;
                if (typeof part?.text?.value === "string") return part.text.value;
                return JSON.stringify(part);
              }).join(" ");
            } else if (typeof s.content === "string") {
              text = s.content;
            } else {
              text = JSON.stringify(s.content);
            }
          } else if (typeof s === "string") {
            text = s;
          } else {
            text = JSON.stringify(s);
          }
          return {
            text: normalizeNewlines(text),
            role: s?.role,
            time: s?.time,
            duration: s?.duration
          };
        }).filter((s) => s.text && String(s.text).trim().length > 0);
      } catch {
        return [];
      }
    }
    const plain = () => getPlain(value);
    const full = () => getFull(value);
    const plainLines = () => plain().split("\n");
    const segments = () => asSegments(value);
    const hasStructuredTranscript = () => segments().length > 0;
    const isLong = () => {
      if (maxLines != null) {
        return plainLines().length > maxLines;
      }
      return plain().length > limit;
    };
    const collapsedText = () => {
      const p = plain();
      if (!isLong()) return p;
      if (maxLines != null) {
        return plainLines().slice(0, maxLines).join("\n");
      }
      return p.slice(0, limit);
    };
    function formatTime(raw) {
      if (!raw) return null;
      try {
        const d = new Date(raw);
        if (Number.isNaN(d.getTime())) return raw;
        return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
      } catch {
        return raw;
      }
    }
    function formatDuration(raw) {
      if (raw == null || !Number.isFinite(raw)) return null;
      const total = Number(raw);
      const totalSec = Math.floor(total);
      const m = Math.floor(totalSec / 60);
      const s = totalSec % 60;
      const mm = String(m).padStart(2, "0");
      const ss = String(s).padStart(2, "0");
      return `${mm}:${ss}`;
    }
    function normalizeRole(role) {
      if (!role) return "Assistant";
      const r = role.trim();
      if (!r) return "Assistant";
      return r.charAt(0).toUpperCase() + r.slice(1);
    }
    function isUserRole(role) {
      const r = role?.toLowerCase() ?? "";
      return r === "user" || r === "customer" || r === "caller";
    }
    function splitSystem(text) {
      const system = [];
      const main = text.replace(/<([^>]+)>/g, (_m, inner) => {
        const cleaned = String(inner).trim();
        if (cleaned) system.push(cleaned);
        return "";
      }).trim();
      return { main, system };
    }
    if (expanded) {
      $$renderer2.push("<!--[-->");
      $$renderer2.push(`<div${attr_class(`mt-1 max-h-96 cursor-text select-text overflow-y-auto rounded border-thin border-rc-gray-600 bg-rc-gray-900 p-2 pr-4 text-sm text-rc-gray-200 ${className}`)}>`);
      if (hasStructuredTranscript()) {
        $$renderer2.push("<!--[-->");
        $$renderer2.push(`<div class="space-y-3"><!--[-->`);
        const each_array = ensure_array_like(segments());
        for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
          let seg = each_array[$$index_1];
          const userSide = isUserRole(seg.role);
          const parts = splitSystem(seg.text);
          const t = formatTime(seg.time);
          const d = formatDuration(seg.duration);
          $$renderer2.push(`<div${attr_class(`flex ${userSide ? "justify-end" : "justify-start"}`)}><div${attr_class(`max-w-[70%] rounded-md px-3 py-2 text-sm shadow-sm ${userSide ? "bg-rc-gray-600 text-rc-gray-100" : "bg-rc-gray-700 text-rc-gray-100"}`)}><div${attr_class(`my-1 text-xs font-semibold uppercase text-rc-green-200 ${userSide ? "text-right" : "text-left"}`)}>${escape_html(normalizeRole(seg.role))}</div> <div${attr_class(`py-1 text-sm ${userSide ? "text-right" : "text-left"}`)}>`);
          if (parts.main) {
            $$renderer2.push("<!--[-->");
            $$renderer2.push(`<div>${escape_html(parts.main)}</div>`);
          } else {
            $$renderer2.push("<!--[!-->");
          }
          $$renderer2.push(`<!--]--> <!--[-->`);
          const each_array_1 = ensure_array_like(parts.system);
          for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
            let sys = each_array_1[$$index];
            $$renderer2.push(`<div class="mt-1 text-xs italic text-rc-gray-200">&lt;${escape_html(sys)}></div>`);
          }
          $$renderer2.push(`<!--]--></div> `);
          if (t || d) {
            $$renderer2.push("<!--[-->");
            $$renderer2.push(`<div${attr_class(`mt-1 text-[11px] text-rc-gray-300 ${userSide ? "text-right" : "text-left"}`)}>`);
            if (t) {
              $$renderer2.push("<!--[-->");
              $$renderer2.push(`${escape_html(t)}`);
            } else {
              $$renderer2.push("<!--[!-->");
            }
            $$renderer2.push(`<!--]--> `);
            if (t && d) {
              $$renderer2.push("<!--[-->");
              $$renderer2.push(`·`);
            } else {
              $$renderer2.push("<!--[!-->");
            }
            $$renderer2.push(`<!--]--> `);
            if (d) {
              $$renderer2.push("<!--[-->");
              $$renderer2.push(`${escape_html(d)}`);
            } else {
              $$renderer2.push("<!--[!-->");
            }
            $$renderer2.push(`<!--]--></div>`);
          } else {
            $$renderer2.push("<!--[!-->");
          }
          $$renderer2.push(`<!--]--></div></div>`);
        }
        $$renderer2.push(`<!--]--></div>`);
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push(`<div class="whitespace-pre-wrap break-words">`);
        if (highlightPrompt) {
          $$renderer2.push("<!--[-->");
          $$renderer2.push(`${html(highlightPromptText(full()))}`);
        } else {
          $$renderer2.push("<!--[!-->");
          $$renderer2.push(`${escape_html(full())}`);
        }
        $$renderer2.push(`<!--]--></div>`);
      }
      $$renderer2.push(`<!--]--></div> <div class="mt-2 pr-2 text-right"><button class="text-rc-green-200 hover:text-rc-green-100">${escape_html(expandedLabel)}</button></div>`);
    } else {
      $$renderer2.push("<!--[!-->");
      $$renderer2.push(`<div${attr_class(`mt-1 cursor-text select-text rounded bg-rc-gray-900 p-2 text-sm text-rc-gray-200 ${className}`)}><span class="whitespace-pre-wrap break-words">`);
      if (highlightPrompt) {
        $$renderer2.push("<!--[-->");
        $$renderer2.push(`${html(highlightPromptText(collapsedText()))}`);
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push(`${escape_html(collapsedText())}`);
      }
      $$renderer2.push(`<!--]--></span> `);
      if (isLong()) {
        $$renderer2.push("<!--[-->");
        $$renderer2.push(`<button class="inline-flex text-sm text-rc-green-200 hover:text-rc-green-100">${escape_html(collapsedLabel)}</button>`);
      } else {
        $$renderer2.push("<!--[!-->");
      }
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      value,
      limit,
      maxLines,
      className,
      expandedLabel,
      collapsedLabel,
      initiallyExpanded,
      stopPropagation,
      expanded,
      treatPlainText,
      highlightPrompt
    });
  });
}
const TranscriptSegmentSchema = z.object({
  text: z.string(),
  role: z.string(),
  // 'Agent' or 'User'
  time: z.string(),
  // ISO timestamp
  duration: z.number()
});
const CallSchema = z.object({
  callId: z.string(),
  phoneNumber: z.string().optional(),
  duration: z.number().optional(),
  audioUrl: z.string().url().optional(),
  // Make optional since it's undefined
  // Accept both string (JSON) and array of objects
  transcript: z.union([z.string(), z.array(TranscriptSegmentSchema)]).optional(),
  createdAt: z.number()
});
const PaginatedCallsResponseSchema = z.object({
  limit: z.number(),
  items: z.array(CallSchema),
  lastCallId: z.string().optional()
});
const StepTraceSchema = z.object({
  traceId: z.string(),
  callId: z.string(),
  scopeId: z.string(),
  workflowId: z.string(),
  workflowRunId: z.string(),
  name: z.string().optional(),
  renderedPrompt: z.string(),
  receivedContext: z.union([z.string(), z.record(z.any())]),
  receivedPrompt: z.string(),
  stringifiedConversation: z.string(),
  response: z.string(),
  model: z.string(),
  createdAt: z.number()
});
z.object({
  items: z.array(StepTraceSchema),
  limit: z.number(),
  lastTraceId: z.string().optional()
});
class TelescopeClient {
  /**
   * @param fetchFn Custom fetch function (e.g., from SvelteKit's load context). Defaults to global fetch if not provided.
   */
  constructor(fetchFn = globalThis.fetch) {
    this.fetchFn = fetchFn;
  }
  /**
   * Get the actual URL to use (always uses proxy)
   */
  getUrl(path) {
    const cleanPath = path.startsWith("/") ? path.slice(1) : path;
    const pathWithoutDev = cleanPath.replace(/^dev\//, "");
    return `/traces/api/proxy/${pathWithoutDev}`;
  }
  async fetch(method = "GET", path, schema) {
    const url = this.getUrl(path);
    const headers = {};
    const response = await this.fetchFn(url, { method, headers });
    if (!response) {
      throw new Error("No response from server");
    }
    if (!response.ok) {
      throw new Error(`Error fetching data: ${response.statusText}`);
    }
    if (schema) {
      return schema.parse(await response.json());
    }
    return response;
  }
  /**
   * Get a list of calls
   * @param phoneNumber full or partial phone number
   * @param limit number of calls to fetch
   * @param lastCallId id of the last call from the previous page, for pagination
   * @returns a list of calls
   */
  async getCalls(params = {}) {
    const searchParams = new URLSearchParams({ limit: params.limit?.toString() ?? "10" });
    if (params.lastCallId) searchParams.append("lastCallId", params.lastCallId);
    if (params.phoneNumber) searchParams.append("phoneNumber", params.phoneNumber);
    const res = await this.fetch("GET", `/calls?${searchParams.toString()}`);
    if (!res.ok) {
      throw new Error(`Error fetching calls: ${res.status} ${res.statusText}`);
    }
    const json = await res.json();
    if (Array.isArray(json?.items)) {
      json.items = json.items.map((it) => ({
        ...it,
        phoneNumber: typeof it?.phoneNumber === "string" ? it.phoneNumber : ""
      }));
    } else {
      json.items = [];
    }
    return PaginatedCallsResponseSchema.parse(json);
  }
  /**
   * Get a single call by ID
   * @param callId the call ID
   * @returns a single call
   */
  async getCall(callId) {
    return await this.fetch("GET", `/calls/${callId}`, CallSchema);
  }
  /**
   * Get step traces for a call
   * @param callId the call ID
   * @param limit number of traces to fetch
   * @param lastTraceId id of the last trace from the previous page, for pagination
   * @returns paginated step traces
   */
  async getStepTraces(callId, limit) {
    const params = new URLSearchParams();
    if (limit) params.set("limit", String(limit));
    const path = `/calls/${callId}/step-traces${params.toString() ? `?${params.toString()}` : ""}`;
    const res = await this.fetch("GET", path);
    if (!res.ok) {
      throw new Error(`Failed to fetch step traces: ${res.status} ${res.statusText}`);
    }
    return res.json();
  }
}

export { CollapseExpand as C, TelescopeClient as T, mockGenerator as m };
//# sourceMappingURL=client-DtDK0-V3.js.map
