Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
} from './types';
import { getSiteErrorView } from './get-site-error-view';
import type { SiteInfo } from '../../lib/state/redux/slice-sites';
import { useKapaAI } from './use-kapa-ai';

export function SiteErrorModal({
error,
Expand All @@ -38,6 +39,7 @@ export function SiteErrorModal({
isSubmittingReport,
handleSubmitReport,
} = useErrorReporting(site);
const kapaAI = useKapaAI();

const helpers: PresentationHelpers = {
deleteSite: () => {
Expand Down Expand Up @@ -69,6 +71,9 @@ export function SiteErrorModal({
});

const detailText = formatErrorDetails(errorDetails);
const shouldShowKapaButton =
!isReporting && detailText && kapaAI.isEnabled();

return (
<Modal
title={
Expand Down Expand Up @@ -143,8 +148,18 @@ export function SiteErrorModal({
</p>
)}
</div>
{view.actions.length || !view.isDeveloperError ? (
{view.actions.length || !view.isDeveloperError || detailText ? (
<div className={css.errorModalFooter}>
{shouldShowKapaButton && (
<Button
variant="secondary"
onClick={() =>
kapaAI.openWithErrorMessage(detailText!)
}
>
Troubleshoot with AI
</Button>
)}
{!view.isDeveloperError &&
!view.hideReportButton &&
!isReporting &&
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useCallback, useRef } from 'react';

const KAPA_WEBSITE_ID = 'a8b85529-1773-4710-b35f-c9ebc70ffcb6';
const KAPA_SCRIPT_ID = 'kapa-widget-script';

declare global {
interface Window {
Kapa?: {
open: (options?: {
mode?: 'ai' | 'search';
query?: string;
submit?: boolean;
}) => void;
close: () => void;
render: (options?: { onRender?: () => void }) => void;
unmount: () => void;
};
}
}

function loadKapaScript(): Promise<void> {
return new Promise((resolve) => {
// Check if script already exists and loaded
if (document.getElementById(KAPA_SCRIPT_ID)) {
if (window.Kapa) {
resolve();
} else {
// Script exists but not loaded yet, wait for it
const checkKapa = setInterval(() => {
if (window.Kapa) {
clearInterval(checkKapa);
resolve();
}
}, 100);
setTimeout(() => clearInterval(checkKapa), 5000);
}
return;
}

const script = document.createElement('script');
script.id = KAPA_SCRIPT_ID;
script.src = 'https://widget.kapa.ai/kapa-widget.bundle.js';
script.async = true;
script.setAttribute('data-website-id', KAPA_WEBSITE_ID);
script.setAttribute(
'data-project-name',
'WordPress Playground AI Assistant'
);
script.setAttribute('data-project-color', '#3858e9');
script.setAttribute(
'data-project-logo',
'https://wordpress.github.io/wordpress-playground/img/playground-logo.svg'
);
script.setAttribute('data-button-hide', 'true');
script.setAttribute('data-modal-z-index', '100001');
script.setAttribute('data-scale-factor', '1.3');

script.onload = () => {
const checkKapa = setInterval(() => {
if (window.Kapa) {
clearInterval(checkKapa);
resolve();
}
}, 100);
setTimeout(() => clearInterval(checkKapa), 5000);
};

document.body.appendChild(script);
});
}

export function useKapaAI() {
const hasSubmittedQuery = useRef(false);
const isEnabled = () => {
return (
window.location.hostname === 'playground.wordpress.net' ||
process.env.NODE_ENV === 'development'
);
};

const openWithErrorMessage = useCallback(async (errorMessage: string) => {
if (!isEnabled()) {
return;
}

await loadKapaScript();

if (window.Kapa) {
if (hasSubmittedQuery.current) {
window.Kapa.open();
} else {
const urlParams = new URLSearchParams(window.location.search);
const hasExternalBlueprint = urlParams.has('blueprint-url');
const contextPrefix = hasExternalBlueprint
? ''
: `Given the URL query parameters ${window.location.search}, `;

window.Kapa.open({
mode: 'ai',
query: `${contextPrefix}Suggest a solution or troubleshooting steps for the following error: ${errorMessage}`,
submit: true,
});
hasSubmittedQuery.current = true;
}
}
}, []);

return {
isEnabled,
openWithErrorMessage,
};
}
4 changes: 2 additions & 2 deletions packages/playground/website/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export default defineConfig(({ command, mode }) => {
'CORS_PROXY_URL' in process.env
? process.env.CORS_PROXY_URL
: mode === 'production'
? 'https://wordpress-playground-cors-proxy.net/?'
: '/cors-proxy/?';
? 'https://wordpress-playground-cors-proxy.net/?'
: '/cors-proxy/?';

return {
// Split traffic from this server on dev so that the iframe content and
Expand Down