"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};

// src/components/chat/Input.tsx
var Input_exports = {};
__export(Input_exports, {
  Input: () => Input
});
module.exports = __toCommonJS(Input_exports);
var import_react4 = require("react");

// src/components/chat/ChatContext.tsx
var import_react = __toESM(require("react"));
var import_jsx_runtime = require("react/jsx-runtime");
var ChatContext = import_react.default.createContext(void 0);
function useChatContext() {
  const context = import_react.default.useContext(ChatContext);
  if (context === void 0) {
    throw new Error(
      "Context not found. Did you forget to wrap your app in a <ChatContextProvider> component?"
    );
  }
  return context;
}

// src/components/chat/Textarea.tsx
var import_react2 = require("react");
var import_jsx_runtime2 = require("react/jsx-runtime");
var AutoResizingTextarea = (0, import_react2.forwardRef)(
  ({
    maxRows = 1,
    placeholder,
    value,
    onChange,
    onKeyDown,
    onCompositionStart,
    onCompositionEnd,
    autoFocus
  }, ref) => {
    const internalTextareaRef = (0, import_react2.useRef)(null);
    const [maxHeight, setMaxHeight] = (0, import_react2.useState)(0);
    (0, import_react2.useImperativeHandle)(ref, () => internalTextareaRef.current);
    (0, import_react2.useEffect)(() => {
      const calculateMaxHeight = () => {
        const textarea = internalTextareaRef.current;
        if (textarea) {
          textarea.style.height = "auto";
          const singleRowHeight = textarea.scrollHeight;
          setMaxHeight(singleRowHeight * maxRows);
          if (autoFocus) {
            textarea.focus();
          }
        }
      };
      calculateMaxHeight();
    }, [maxRows]);
    (0, import_react2.useEffect)(() => {
      const textarea = internalTextareaRef.current;
      if (textarea) {
        textarea.style.height = "auto";
        textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
      }
    }, [value, maxHeight]);
    return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
      "textarea",
      {
        ref: internalTextareaRef,
        value,
        onChange,
        onKeyDown,
        onCompositionStart,
        onCompositionEnd,
        placeholder,
        style: {
          overflow: "auto",
          resize: "none",
          maxHeight: `${maxHeight}px`
        },
        rows: 1
      }
    );
  }
);
var Textarea_default = AutoResizingTextarea;

// src/hooks/use-push-to-talk.tsx
var import_react_core = require("@copilotkit/react-core");
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
var import_react3 = require("react");
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
  if (!mediaStreamRef.current || !audioContextRef.current) {
    mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
    audioContextRef.current = new window.AudioContext();
    yield audioContextRef.current.resume();
  }
  mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
  mediaRecorderRef.current.start(1e3);
  mediaRecorderRef.current.ondataavailable = (event) => {
    recordedChunks.push(event.data);
  };
  mediaRecorderRef.current.onstop = onStop;
});
var stopRecording = (mediaRecorderRef) => {
  if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
    mediaRecorderRef.current.stop();
  }
};
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
  const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
  const formData = new FormData();
  formData.append("file", completeBlob, "recording.mp4");
  const response = yield fetch(transcribeAudioUrl, {
    method: "POST",
    body: formData
  });
  if (!response.ok) {
    throw new Error(`Error: ${response.statusText}`);
  }
  const transcription = yield response.json();
  return transcription.text;
});
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
  const encodedText = encodeURIComponent(text);
  const url = `${textToSpeechUrl}?text=${encodedText}`;
  fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
    const source = audioContext.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(audioContext.destination);
    source.start(0);
  }).catch((error) => {
    console.error("Error with decoding audio data", error);
  });
};
var usePushToTalk = ({
  sendFunction,
  inProgress
}) => {
  const [pushToTalkState, setPushToTalkState] = (0, import_react3.useState)("idle");
  const mediaStreamRef = (0, import_react3.useRef)(null);
  const audioContextRef = (0, import_react3.useRef)(null);
  const mediaRecorderRef = (0, import_react3.useRef)(null);
  const recordedChunks = (0, import_react3.useRef)([]);
  const generalContext = (0, import_react_core.useCopilotContext)();
  const messagesContext = (0, import_react_core.useCopilotMessagesContext)();
  const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
  const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react3.useState)(null);
  (0, import_react3.useEffect)(() => {
    if (pushToTalkState === "recording") {
      startRecording(
        mediaStreamRef,
        mediaRecorderRef,
        audioContextRef,
        recordedChunks.current,
        () => {
          setPushToTalkState("transcribing");
        }
      );
    } else {
      stopRecording(mediaRecorderRef);
      if (pushToTalkState === "transcribing") {
        transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
          (transcription) => __async(void 0, null, function* () {
            recordedChunks.current = [];
            setPushToTalkState("idle");
            const message = yield sendFunction(transcription);
            setStartReadingFromMessageId(message.id);
          })
        );
      }
    }
    return () => {
      stopRecording(mediaRecorderRef);
    };
  }, [pushToTalkState]);
  (0, import_react3.useEffect)(() => {
    if (inProgress === false && startReadingFromMessageId) {
      const lastMessageIndex = context.messages.findIndex(
        (message) => message.id === startReadingFromMessageId
      );
      const aguiMessages = (0, import_runtime_client_gql.gqlToAGUI)(context.messages);
      const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
      const text = messagesAfterLast.map((message) => message.content).join("\n");
      playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
      setStartReadingFromMessageId(null);
    }
  }, [startReadingFromMessageId, inProgress]);
  return { pushToTalkState, setPushToTalkState };
};

// src/components/chat/Input.tsx
var import_react_core2 = require("@copilotkit/react-core");

// src/hooks/use-dark-mode.ts
var useDarkMode = () => {
  if (typeof window === "undefined")
    return false;
  return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
};

// src/components/chat/PoweredByTag.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
function PoweredByTag({ showPoweredBy = true }) {
  const isDark = useDarkMode();
  if (!showPoweredBy) {
    return null;
  }
  const poweredByStyle = {
    visibility: "visible",
    display: "block",
    position: "static",
    textAlign: "center",
    fontSize: "12px",
    padding: "3px 0",
    color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
  };
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
}

// src/components/chat/Input.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
var MAX_NEWLINES = 6;
var Input = ({
  inProgress,
  onSend,
  isVisible = false,
  onStop,
  onUpload,
  hideStopButton = false
}) => {
  var _a, _b;
  const context = useChatContext();
  const copilotContext = (0, import_react_core2.useCopilotContext)();
  const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
  const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
  const textareaRef = (0, import_react4.useRef)(null);
  const [isComposing, setIsComposing] = (0, import_react4.useState)(false);
  const handleDivClick = (event) => {
    var _a2;
    const target = event.target;
    if (target.closest("button"))
      return;
    if (target.tagName === "TEXTAREA")
      return;
    (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
  };
  const [text, setText] = (0, import_react4.useState)("");
  const send = () => {
    var _a2;
    if (inProgress)
      return;
    onSend(text);
    setText("");
    (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
  };
  const { pushToTalkState, setPushToTalkState } = usePushToTalk({
    sendFunction: onSend,
    inProgress
  });
  const isInProgress = inProgress || pushToTalkState === "transcribing";
  const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
  const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
  const canSend = (0, import_react4.useMemo)(() => {
    var _a2;
    const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
    const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
    return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
  }, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
  const canStop = (0, import_react4.useMemo)(() => {
    return isInProgress && !hideStopButton;
  }, [isInProgress, hideStopButton]);
  const sendDisabled = !canSend && !canStop;
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
    /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
      /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
        Textarea_default,
        {
          ref: textareaRef,
          placeholder: context.labels.placeholder,
          autoFocus: false,
          maxRows: MAX_NEWLINES,
          value: text,
          onChange: (event) => setText(event.target.value),
          onCompositionStart: () => setIsComposing(true),
          onCompositionEnd: () => setIsComposing(false),
          onKeyDown: (event) => {
            if (event.key === "Enter" && !event.shiftKey && !isComposing) {
              event.preventDefault();
              if (canSend) {
                send();
              }
            }
          }
        }
      ),
      /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitInputControls", children: [
        onUpload && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
        /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flexGrow: 1 } }),
        showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
          "button",
          {
            onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
            className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
            children: context.icons.pushToTalkIcon
          }
        ),
        /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
          "button",
          {
            disabled: sendDisabled,
            onClick: isInProgress && !hideStopButton ? onStop : send,
            "data-copilotkit-in-progress": inProgress,
            "data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
            className: "copilotKitInputControlButton",
            children: buttonIcon
          }
        )
      ] })
    ] }),
    /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PoweredByTag, { showPoweredBy })
  ] });
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Input
});
//# sourceMappingURL=Input.js.map