File size: 3,117 Bytes
f52d137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { useCallback, useState } from "react";
import { FormData } from "../types";
import {
  createStartDemoPayload,
  readFileAsText,
  startDemo,
} from "../utils/api";
import { useHealthCheck } from "./useHealthCheck";

interface HealthCheckProgress {
  attempt: number;
  maxAttempts: number;
}

interface UseStartDemoOptions {
  onSuccess?: () => void;
  onError?: (error: Error) => void;
}

interface UseStartDemoReturn {
  // States
  isStarting: boolean;
  iframeUrl: string;
  iframeLoading: boolean;
  healthCheckProgress: HealthCheckProgress | null;

  // Actions
  startDemoSession: (
    formData: FormData,
    loginLabel: string,
    accessToken: string | null,
    options?: UseStartDemoOptions & { logPrefix?: string }
  ) => Promise<void>;
  resetDemo: () => void;
  setIframeLoaded: () => void;
}

export const useStartDemo = (): UseStartDemoReturn => {
  const [isStarting, setIsStarting] = useState<boolean>(false);
  const [iframeUrl, setIframeUrl] = useState<string>("");
  const [iframeLoading, setIframeLoading] = useState<boolean>(false);

  const { healthCheckProgress, startHealthCheck } = useHealthCheck();

  const startDemoSession = useCallback(async (
    formData: FormData,
    loginLabel: string,
    accessToken: string | null,
    options: UseStartDemoOptions & { logPrefix?: string } = {}
  ) => {
    const {
      onSuccess,
      onError,
      logPrefix = "Demo startup"
    } = options;

    setIsStarting(true);
    setIframeLoading(true);

    try {
      // Read MCP file if present
      const mcpText = formData.mcpFile
        ? await readFileAsText(formData.mcpFile)
        : null;

      // Create and send payload
      const payload = createStartDemoPayload(
        formData.model,
        formData.provider,
        loginLabel,
        mcpText,
      );

      const result = await startDemo(payload, accessToken);
      setIframeUrl(result.iframe_url);

      // Start health checking in the background
      await startHealthCheck(result.health_url, {
        logPrefix: `${logPrefix} health check`,
        onSuccess: () => {
          setIframeLoading(false);
          if (onSuccess) {
            onSuccess();
          }
        },
        onError: (healthCheckError) => {
          setIframeLoading(false);
          if (onError) {
            onError(new Error("Server startup timed out. The application may still be loading in the background."));
          }
        },
      });
    } catch (error) {
      console.error(`${logPrefix} failed:`, error);
      setIsStarting(false);
      setIframeLoading(false);

      if (onError) {
        onError(error as Error);
      }
    } finally {
      setIsStarting(false);
    }
  }, [startHealthCheck]);

  const resetDemo = useCallback(() => {
    setIframeUrl("");
    setIframeLoading(false);
    setIsStarting(false);
  }, []);

  const setIframeLoaded = useCallback(() => {
    setIframeLoading(false);
  }, []);

  return {
    // States
    isStarting,
    iframeUrl,
    iframeLoading,
    healthCheckProgress,

    // Actions
    startDemoSession,
    resetDemo,
    setIframeLoaded,
  };
};