@mvriu5/payload-ai 0.5.10 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
3
  import { useConfig } from "@payloadcms/ui";
3
4
  import { formatAdminURL } from "payload/shared";
4
5
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -44,15 +45,25 @@ const getProviderIcon = (provider)=>{
44
45
  };
45
46
  switch(provider){
46
47
  case "claude":
47
- return /*#__PURE__*/ React.createElement(ClaudeIcon, iconProps);
48
+ return /*#__PURE__*/ _jsx(ClaudeIcon, {
49
+ ...iconProps
50
+ });
48
51
  case "google":
49
- return /*#__PURE__*/ React.createElement(GoogleGeminiIcon, iconProps);
52
+ return /*#__PURE__*/ _jsx(GoogleGeminiIcon, {
53
+ ...iconProps
54
+ });
50
55
  case "mistral":
51
- return /*#__PURE__*/ React.createElement(MistralAiIcon, iconProps);
56
+ return /*#__PURE__*/ _jsx(MistralAiIcon, {
57
+ ...iconProps
58
+ });
52
59
  case "openai":
53
- return /*#__PURE__*/ React.createElement(OpenaiIcon, iconProps);
60
+ return /*#__PURE__*/ _jsx(OpenaiIcon, {
61
+ ...iconProps
62
+ });
54
63
  case "openrouter":
55
- return /*#__PURE__*/ React.createElement(OpenrouterIcon, iconProps);
64
+ return /*#__PURE__*/ _jsx(OpenrouterIcon, {
65
+ ...iconProps
66
+ });
56
67
  default:
57
68
  return null;
58
69
  }
@@ -73,7 +84,7 @@ const parseSSEEvent = (chunk)=>{
73
84
  if (!eventName) return null;
74
85
  try {
75
86
  const data = JSON.parse(dataLines.join("\n"));
76
- if (eventName !== "text" && eventName !== "proposals" && eventName !== "error" && eventName !== "done") {
87
+ if (eventName !== "text" && eventName !== "proposals" && eventName !== "error" && eventName !== "done" && eventName !== "debug") {
77
88
  return null;
78
89
  }
79
90
  return {
@@ -85,6 +96,59 @@ const parseSSEEvent = (chunk)=>{
85
96
  }
86
97
  };
87
98
  const sanitizeResponseText = (value)=>value.replace(/\*\*/g, "");
99
+ const getDebugReasonLabel = (reason)=>{
100
+ switch(reason){
101
+ case "model_did_not_call_tool":
102
+ return "Model did not create a proposal tool call.";
103
+ case "proposal_created":
104
+ return "Proposal created.";
105
+ case "tool_validation_failed":
106
+ return "Tool validation failed before a proposal could be created.";
107
+ case "write_intent_without_tool_call":
108
+ return "The selected model did not produce the required proposal tool call for this content change.";
109
+ default:
110
+ return "Unknown";
111
+ }
112
+ };
113
+ const getApplyDebugReasonLabel = (reason)=>{
114
+ switch(reason){
115
+ case "unauthorized":
116
+ return "Request was not authorized.";
117
+ case "missing_proposal":
118
+ return "No proposal was submitted to apply.";
119
+ case "invalid_signature":
120
+ return "Proposal signature was invalid or expired.";
121
+ case "invalid_proposal_shape":
122
+ return "Proposal shape was invalid.";
123
+ case "sensitive_data_in_data":
124
+ case "sensitive_data_in_localized_data":
125
+ return "Proposal contained sensitive data.";
126
+ case "unknown_global":
127
+ return "Target global was not found.";
128
+ case "unknown_or_disallowed_collection":
129
+ return "Target collection is unknown or not allowed.";
130
+ case "invalid_collection_write_shape":
131
+ return "Proposal data does not match the target collection schema.";
132
+ case "invalid_global_write_shape":
133
+ return "Proposal data does not match the target global schema.";
134
+ case "localized_create_without_locales":
135
+ return "Localized create proposal had no locale entries.";
136
+ case "missing_auth_password":
137
+ return "Auth create proposal was missing a password.";
138
+ case "missing_auth_email":
139
+ return "Auth create proposal was missing an email.";
140
+ case "payload_operation_failed":
141
+ return "Payload rejected the write operation.";
142
+ default:
143
+ return "Unknown";
144
+ }
145
+ };
146
+ const getChatDebugMessage = (debugInfo)=>{
147
+ if (debugInfo.toolFailures?.length) {
148
+ return debugInfo.toolFailures[0]?.message || getDebugReasonLabel(debugInfo.reason);
149
+ }
150
+ return getDebugReasonLabel(debugInfo.reason);
151
+ };
88
152
  const isMentionBoundary = (character)=>{
89
153
  return character === undefined || /\s/.test(character);
90
154
  };
@@ -111,6 +175,7 @@ const getActiveMentionRange = (valueBeforeCaret)=>{
111
175
  };
112
176
  const svgNamespace = "http://www.w3.org/2000/svg";
113
177
  const auditLogCollectionSlug = "payload-ai-auditlog";
178
+ const responseOnlyToastCooldownMs = 10000;
114
179
  const appendSvgPath = (svg, d)=>{
115
180
  const path = document.createElementNS(svgNamespace, "path");
116
181
  path.setAttribute("d", d);
@@ -182,6 +247,8 @@ const AIInput = ()=>{
182
247
  const [appliedProposalIndexes, setAppliedProposalIndexes] = useState([]);
183
248
  const [response, setResponse] = useState("");
184
249
  const [tokenUsage, setTokenUsage] = useState(null);
250
+ const [chatDebugInfo, setChatDebugInfo] = useState(null);
251
+ const [applyDebugInfo, setApplyDebugInfo] = useState(null);
185
252
  const [error, setError] = useState("");
186
253
  const [proposals, setProposals] = useState([]);
187
254
  const [appliedChanges, setAppliedChanges] = useState([]);
@@ -220,7 +287,7 @@ const AIInput = ()=>{
220
287
  const timeout = window.setTimeout(()=>{
221
288
  setResponse("");
222
289
  clearInput();
223
- }, 5000);
290
+ }, responseOnlyToastCooldownMs);
224
291
  return ()=>window.clearTimeout(timeout);
225
292
  }, [
226
293
  error,
@@ -293,6 +360,9 @@ const AIInput = ()=>{
293
360
  ...filteredMentionOptions,
294
361
  ...documentSuggestions
295
362
  ];
363
+ const shouldShowChatDebugInfo = Boolean(chatDebugInfo) && (Boolean(error) || chatDebugInfo?.reason !== "proposal_created");
364
+ const shouldShowApplyDebugInfo = Boolean(applyDebugInfo) && Boolean(error);
365
+ const actionToastDescription = response;
296
366
  const getTextBeforeCaret = (element)=>{
297
367
  const selection = window.getSelection();
298
368
  if (!selection || selection.rangeCount === 0) return "";
@@ -463,6 +533,8 @@ const AIInput = ()=>{
463
533
  setProposals([]);
464
534
  setResponse("");
465
535
  setTokenUsage(null);
536
+ setChatDebugInfo(null);
537
+ setApplyDebugInfo(null);
466
538
  try {
467
539
  const res = await fetch(formatAdminURL({
468
540
  apiRoute: config.routes.api,
@@ -488,7 +560,10 @@ const AIInput = ()=>{
488
560
  const reader = res.body.getReader();
489
561
  const decoder = new TextDecoder();
490
562
  let buffer = "";
563
+ let finalDebugInfo = null;
491
564
  let receivedProposals = [];
565
+ let receivedText = "";
566
+ let receivedVisibleText = "";
492
567
  while(true){
493
568
  const { done, value } = await reader.read();
494
569
  if (done) break;
@@ -502,7 +577,10 @@ const AIInput = ()=>{
502
577
  if (!event) continue;
503
578
  if (event.event === "text") {
504
579
  if (event.data.delta) {
505
- setResponse((current)=>current + sanitizeResponseText(event.data.delta || ""));
580
+ const nextDelta = sanitizeResponseText(event.data.delta || "");
581
+ receivedText += nextDelta;
582
+ receivedVisibleText += nextDelta.replace(/\s+/g, "");
583
+ setResponse((current)=>current + nextDelta);
506
584
  }
507
585
  continue;
508
586
  }
@@ -512,6 +590,22 @@ const AIInput = ()=>{
512
590
  setTokenUsage(event.data.usage || null);
513
591
  continue;
514
592
  }
593
+ if (event.event === "debug") {
594
+ finalDebugInfo = event.data;
595
+ setChatDebugInfo(event.data);
596
+ if ((event.data.proposalCount || 0) === 0 && !receivedVisibleText) {
597
+ // Show specific tool validation message if present, otherwise a generic no‑action message
598
+ if (event.data.reason === "tool_validation_failed") {
599
+ const msg = getChatDebugMessage(event.data);
600
+ setResponse(msg);
601
+ // Auto‑clear after the standard toast timeout
602
+ window.setTimeout(()=>setResponse(""), responseOnlyToastCooldownMs);
603
+ } else {
604
+ setResponse("No action needed");
605
+ }
606
+ }
607
+ continue;
608
+ }
515
609
  if (event.event === "error") {
516
610
  throw new Error(event.data.error || "AI request failed");
517
611
  }
@@ -523,16 +617,42 @@ const AIInput = ()=>{
523
617
  setProposals(receivedProposals);
524
618
  setTokenUsage(finalEvent.data.usage || null);
525
619
  }
620
+ if (finalEvent?.event === "debug") {
621
+ finalDebugInfo = finalEvent.data;
622
+ setChatDebugInfo(finalEvent.data);
623
+ if ((finalEvent.data.proposalCount || 0) === 0 && !receivedVisibleText) {
624
+ // Same logic as above for the final event
625
+ if (finalEvent.data.reason === "tool_validation_failed") {
626
+ setResponse(getChatDebugMessage(finalEvent.data));
627
+ } else {
628
+ setResponse("No action needed");
629
+ }
630
+ }
631
+ }
526
632
  if (finalEvent?.event === "error") {
527
633
  throw new Error(finalEvent.data.error || "AI request failed");
528
634
  }
529
635
  if (receivedProposals.length === 0) {
636
+ if (finalDebugInfo) {
637
+ const debugMessage = getChatDebugMessage(finalDebugInfo);
638
+ const isMeaningfulVisibleText = receivedVisibleText.length >= 12;
639
+ const trimmedReceivedText = receivedText.trim();
640
+ if (!isMeaningfulVisibleText || trimmedReceivedText.length < 12) {
641
+ setResponse(debugMessage);
642
+ } else {
643
+ setResponse((current)=>current.trim() || debugMessage);
644
+ }
645
+ } else {
646
+ // Fallback when no debug info is provided (e.g., tool validation failures without a debug event)
647
+ setResponse("No action needed");
648
+ }
530
649
  clearInput();
531
650
  }
532
651
  } catch (err) {
533
652
  setProposals([]);
534
653
  setResponse("");
535
654
  setTokenUsage(null);
655
+ setApplyDebugInfo(null);
536
656
  setError(err instanceof Error ? err.message : "AI request failed");
537
657
  } finally{
538
658
  setIsLoading(false);
@@ -561,6 +681,7 @@ const AIInput = ()=>{
561
681
  if (!res.ok) {
562
682
  setProposals([]);
563
683
  setResponse("");
684
+ setApplyDebugInfo(result.debug || null);
564
685
  throw new Error(result.error || "Could not apply proposal");
565
686
  }
566
687
  setAppliedProposalIndexes([]);
@@ -568,6 +689,8 @@ const AIInput = ()=>{
568
689
  setProposals([]);
569
690
  setResponse("");
570
691
  setTokenUsage(null);
692
+ setChatDebugInfo(null);
693
+ setApplyDebugInfo(null);
571
694
  if (result.change) {
572
695
  setAppliedChanges((current)=>[
573
696
  result.change,
@@ -582,109 +705,192 @@ const AIInput = ()=>{
582
705
  setIsApplying(false);
583
706
  }
584
707
  };
585
- return /*#__PURE__*/ React.createElement("div", {
586
- className: styles.chatLayout
587
- }, /*#__PURE__*/ React.createElement("div", {
588
- className: styles.chat
589
- }, /*#__PURE__*/ React.createElement("div", {
590
- className: styles.chatHeader
591
- }, /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("h2", {
592
- className: styles.chatTitle
593
- }, "AI Assistant"), /*#__PURE__*/ React.createElement("p", {
594
- className: styles.chatDescription
595
- }, "Ask AI to draft, improve, or analyze content."))), /*#__PURE__*/ React.createElement("div", {
596
- className: styles.chatInputRow
597
- }, /*#__PURE__*/ React.createElement("div", {
598
- className: styles.chatInputSurface
599
- }, /*#__PURE__*/ React.createElement("div", {
600
- className: styles.chatInput,
601
- contentEditable: true,
602
- "data-placeholder": "Ask AI...",
603
- onInput: (event)=>{
604
- const value = event.currentTarget.innerText;
605
- setPrompt(value);
606
- if (!value.trim()) {
607
- setMentions([]);
608
- }
609
- updateMentionState(getTextBeforeCaret(event.currentTarget));
610
- },
611
- onKeyDown: (event)=>{
612
- if (event.key === "ArrowDown" && mentionRange && mentionSuggestions.length > 0) {
613
- const firstOption = mentionPopoverRef.current?.querySelector("button");
614
- if (firstOption) {
615
- event.preventDefault();
616
- firstOption.focus();
617
- return;
618
- }
619
- }
620
- if (event.key === "Enter" && !event.shiftKey) {
621
- event.preventDefault();
622
- void handleSubmit();
623
- }
624
- },
625
- ref: editorRef,
626
- role: "textbox",
627
- suppressContentEditableWarning: true
628
- })), mentionRange && /*#__PURE__*/ React.createElement(MentionPopover, {
629
- containerRef: mentionPopoverRef,
630
- onSelect: insertMention,
631
- style: mentionPopoverPosition ? {
632
- left: `${mentionPopoverPosition.left}px`,
633
- top: `${mentionPopoverPosition.top}px`
634
- } : undefined,
635
- suggestions: mentionSuggestions
636
- })), /*#__PURE__*/ React.createElement("div", {
637
- className: styles.chatActionsRow
638
- }, /*#__PURE__*/ React.createElement("div", {
639
- className: styles.settings
640
- }, /*#__PURE__*/ React.createElement("label", {
641
- className: styles.setting
642
- }, /*#__PURE__*/ React.createElement("span", {
643
- className: styles.settingLabel
644
- }, "Model"), /*#__PURE__*/ React.createElement("div", {
645
- className: styles.selectWrapper
646
- }, getProviderIcon(settingsProvider), /*#__PURE__*/ React.createElement("select", {
647
- className: styles.select,
648
- disabled: !settingsProvider,
649
- onChange: (event)=>setSelectedModel(event.target.value),
650
- value: selectedModel
651
- }, !settingsProvider && /*#__PURE__*/ React.createElement("option", {
652
- value: ""
653
- }, "Select provider in account settings"), settingsProvider && aiModelConfig.providers[settingsProvider].map((model)=>/*#__PURE__*/ React.createElement("option", {
654
- key: model.value,
655
- value: model.value
656
- }, model.label)))))), /*#__PURE__*/ React.createElement("button", {
657
- className: styles.chatButton,
658
- disabled: !prompt.trim() || !settingsProvider || !selectedModel || isLoading,
659
- onClick: ()=>void handleSubmit(),
660
- type: "button"
661
- }, /*#__PURE__*/ React.createElement(Send, {
662
- width: 14,
663
- height: 14
664
- }), isLoading ? "Sending..." : "Send")), /*#__PURE__*/ React.createElement(ActionToast, {
665
- apiRoute: config.routes.api,
666
- appliedProposalIndexes: appliedProposalIndexes,
667
- description: response,
668
- error: error,
669
- getViewURL: getProposalViewURL,
670
- isApplying: isApplying,
671
- onDismiss: ()=>{
672
- setAppliedProposalIndexes([]);
673
- setError("");
674
- setProposals([]);
675
- setResponse("");
676
- setTokenUsage(null);
677
- clearInput();
678
- },
679
- onDismissError: ()=>{
680
- setError("");
681
- },
682
- onApply: (proposal, _index)=>void handleApplyProposal(proposal),
683
- proposals: proposals,
684
- tokenUsage: tokenUsage
685
- })), /*#__PURE__*/ React.createElement(RecentChangesList, {
686
- allChangesURL: allChangesURL,
687
- changes: appliedChanges
688
- }));
708
+ return /*#__PURE__*/ _jsxs("div", {
709
+ className: styles.chatLayout,
710
+ children: [
711
+ /*#__PURE__*/ _jsxs("div", {
712
+ className: styles.chat,
713
+ children: [
714
+ /*#__PURE__*/ _jsx("div", {
715
+ className: styles.chatHeader,
716
+ children: /*#__PURE__*/ _jsxs("div", {
717
+ children: [
718
+ /*#__PURE__*/ _jsx("h2", {
719
+ className: styles.chatTitle,
720
+ children: "AI Assistant"
721
+ }),
722
+ /*#__PURE__*/ _jsx("p", {
723
+ className: styles.chatDescription,
724
+ children: "Ask AI to draft, improve, or analyze content."
725
+ })
726
+ ]
727
+ })
728
+ }),
729
+ /*#__PURE__*/ _jsxs("div", {
730
+ className: styles.chatInputRow,
731
+ children: [
732
+ /*#__PURE__*/ _jsx("div", {
733
+ className: styles.chatInputSurface,
734
+ children: /*#__PURE__*/ _jsx("div", {
735
+ className: styles.chatInput,
736
+ contentEditable: true,
737
+ "data-placeholder": "Ask AI...",
738
+ onInput: (event)=>{
739
+ const value = event.currentTarget.innerText;
740
+ setPrompt(value);
741
+ if (!value.trim()) {
742
+ setMentions([]);
743
+ }
744
+ updateMentionState(getTextBeforeCaret(event.currentTarget));
745
+ },
746
+ onKeyDown: (event)=>{
747
+ if (event.key === "ArrowDown" && mentionRange && mentionSuggestions.length > 0) {
748
+ const firstOption = mentionPopoverRef.current?.querySelector("button");
749
+ if (firstOption) {
750
+ event.preventDefault();
751
+ firstOption.focus();
752
+ return;
753
+ }
754
+ }
755
+ if (event.key === "Enter" && !event.shiftKey) {
756
+ event.preventDefault();
757
+ void handleSubmit();
758
+ }
759
+ },
760
+ ref: editorRef,
761
+ role: "textbox",
762
+ suppressContentEditableWarning: true
763
+ })
764
+ }),
765
+ mentionRange && /*#__PURE__*/ _jsx(MentionPopover, {
766
+ containerRef: mentionPopoverRef,
767
+ onSelect: insertMention,
768
+ style: mentionPopoverPosition ? {
769
+ left: `${mentionPopoverPosition.left}px`,
770
+ top: `${mentionPopoverPosition.top}px`
771
+ } : undefined,
772
+ suggestions: mentionSuggestions
773
+ })
774
+ ]
775
+ }),
776
+ /*#__PURE__*/ _jsxs("div", {
777
+ className: styles.chatActionsRow,
778
+ children: [
779
+ /*#__PURE__*/ _jsx("div", {
780
+ className: styles.settings,
781
+ children: /*#__PURE__*/ _jsxs("label", {
782
+ className: styles.setting,
783
+ children: [
784
+ /*#__PURE__*/ _jsx("span", {
785
+ className: styles.settingLabel,
786
+ children: "Model"
787
+ }),
788
+ /*#__PURE__*/ _jsxs("div", {
789
+ className: styles.selectWrapper,
790
+ children: [
791
+ getProviderIcon(settingsProvider),
792
+ /*#__PURE__*/ _jsxs("select", {
793
+ className: styles.select,
794
+ disabled: !settingsProvider,
795
+ onChange: (event)=>setSelectedModel(event.target.value),
796
+ value: selectedModel,
797
+ children: [
798
+ !settingsProvider && /*#__PURE__*/ _jsx("option", {
799
+ value: "",
800
+ children: "Select provider in account settings"
801
+ }),
802
+ settingsProvider && aiModelConfig.providers[settingsProvider].map((model)=>/*#__PURE__*/ _jsx("option", {
803
+ value: model.value,
804
+ children: model.label
805
+ }, model.value))
806
+ ]
807
+ })
808
+ ]
809
+ })
810
+ ]
811
+ })
812
+ }),
813
+ /*#__PURE__*/ _jsxs("button", {
814
+ className: styles.chatButton,
815
+ disabled: !prompt.trim() || !settingsProvider || !selectedModel || isLoading || Boolean(error) || Boolean(actionToastDescription) || proposals.length > 0,
816
+ onClick: ()=>void handleSubmit(),
817
+ type: "button",
818
+ children: [
819
+ /*#__PURE__*/ _jsx(Send, {
820
+ width: 14,
821
+ height: 14
822
+ }),
823
+ isLoading ? "Sending..." : "Send"
824
+ ]
825
+ })
826
+ ]
827
+ }),
828
+ /*#__PURE__*/ _jsx(ActionToast, {
829
+ apiRoute: config.routes.api,
830
+ appliedProposalIndexes: appliedProposalIndexes,
831
+ description: actionToastDescription,
832
+ error: error,
833
+ getViewURL: getProposalViewURL,
834
+ isApplying: isApplying,
835
+ onDismiss: ()=>{
836
+ setAppliedProposalIndexes([]);
837
+ setError("");
838
+ setProposals([]);
839
+ setResponse("");
840
+ setTokenUsage(null);
841
+ setChatDebugInfo(null);
842
+ setApplyDebugInfo(null);
843
+ clearInput();
844
+ },
845
+ onDismissError: ()=>{
846
+ setError("");
847
+ },
848
+ onApply: (proposal, _index)=>void handleApplyProposal(proposal),
849
+ proposals: proposals,
850
+ prompt: prompt,
851
+ tokenUsage: tokenUsage
852
+ }),
853
+ shouldShowApplyDebugInfo && applyDebugInfo && /*#__PURE__*/ _jsxs("div", {
854
+ className: styles.debugInfo,
855
+ children: [
856
+ /*#__PURE__*/ _jsx("strong", {
857
+ children: "Apply debug"
858
+ }),
859
+ /*#__PURE__*/ _jsx("br", {}),
860
+ "Reason: ",
861
+ getApplyDebugReasonLabel(applyDebugInfo.reason),
862
+ /*#__PURE__*/ _jsx("br", {}),
863
+ "Phase: ",
864
+ applyDebugInfo.phase,
865
+ /*#__PURE__*/ _jsx("br", {}),
866
+ "Target: ",
867
+ applyDebugInfo.collection || applyDebugInfo.slug || "unknown",
868
+ applyDebugInfo.id ? /*#__PURE__*/ _jsxs(_Fragment, {
869
+ children: [
870
+ /*#__PURE__*/ _jsx("br", {}),
871
+ "ID: ",
872
+ applyDebugInfo.id
873
+ ]
874
+ }) : null,
875
+ applyDebugInfo.details ? /*#__PURE__*/ _jsxs(_Fragment, {
876
+ children: [
877
+ /*#__PURE__*/ _jsx("br", {}),
878
+ "Details:",
879
+ /*#__PURE__*/ _jsx("pre", {
880
+ className: styles.debugDetails,
881
+ children: JSON.stringify(applyDebugInfo.details, null, 2)
882
+ })
883
+ ]
884
+ }) : null
885
+ ]
886
+ })
887
+ ]
888
+ }),
889
+ /*#__PURE__*/ _jsx(RecentChangesList, {
890
+ allChangesURL: allChangesURL,
891
+ changes: appliedChanges
892
+ })
893
+ ]
894
+ });
689
895
  };
690
896
  export default AIInput;
@@ -101,8 +101,10 @@
101
101
  background: transparent;
102
102
  border: 0;
103
103
  color: var(--theme-text);
104
+ display: block;
104
105
  font: inherit;
105
- min-height: 84px;
106
+ height: 84px;
107
+ overflow-y: auto;
106
108
  padding: 0;
107
109
  white-space: pre-wrap;
108
110
  width: 100%;
@@ -120,7 +122,10 @@
120
122
  .chatInputSurface {
121
123
  background: var(--theme-input-bg);
122
124
  border: 1px solid var(--theme-elevation-150);
125
+ box-sizing: border-box;
123
126
  border-radius: 4px;
127
+ height: 108px;
128
+ overflow: hidden;
124
129
  padding: 12px;
125
130
  width: 100%;
126
131
  }
@@ -239,6 +244,11 @@
239
244
  white-space: pre-wrap;
240
245
  }
241
246
 
247
+ .debugDetails {
248
+ margin: 8px 0 0;
249
+ white-space: pre-wrap;
250
+ }
251
+
242
252
  .chatResponse {
243
253
  background: var(--theme-elevation-50);
244
254
  border: 1px solid var(--theme-elevation-100);
@@ -285,5 +295,4 @@
285
295
  .chatButton {
286
296
  align-self: stretch;
287
297
  }
288
-
289
298
  }