File size: 2,524 Bytes
243b4bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
async function requestJson(url, options = {}) {
  const res = await fetch(url, { credentials: "include", ...options });
  const text = await res.text();
  let body;
  try {
    body = text ? JSON.parse(text) : null;
  } catch {
    body = { data: null, message: text, success: res.ok };
  }
  if (!res.ok && !(body && body.success === false)) {
    throw new Error((body && body.message) || `HTTP ${res.status}`);
  }
  return body;
}

async function getHealth() {
  return requestJson(window.API_ENDPOINTS.HEALTH);
}

async function getAvailableTimeOptions() {
  const body = await requestJson(window.API_ENDPOINTS.AVAILABLE_TIME);
  return (body && body.data) || [];
}

async function loginUser(minutes) {
  const url = `${window.API_ENDPOINTS.USER_LOGIN}/${minutes}`;
  const res = await requestJson(url);
  if (res && res.success) {
    const durationMs = minutes * 60 * 1000;
    const expiryTime = Date.now() + durationMs;
    localStorage.setItem("session_expiry", expiryTime);
    localStorage.setItem("session_duration_minutes", minutes);
    window.location.href = window.PAGES.CHAT;
  } else {
    throw new Error((res && res.message) || "Failed to start session");
  }
}

async function trainModel() {
  return requestJson(window.API_ENDPOINTS.TRAIN, { method: "GET" });
}

function streamChat({ body, file, onChunk, onDone, onError }) {
  const fd = new FormData();
  fd.append("body", JSON.stringify(body));
  if (file) fd.append("file", file);

  fetch(window.API_ENDPOINTS.CHAT, {
    method: "POST",
    credentials: "include",
    body: fd,
  })
    .then(async (res) => {
      if (!res.ok || !res.body) {
        const txt = await res.text();
        throw new Error(txt || `HTTP ${res.status}`);
      }
      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = "";
      while (true) {
        const { value, done } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        let idx;
        while ((idx = buffer.indexOf("\n")) >= 0) {
          const line = buffer.slice(0, idx).trim();
          buffer = buffer.slice(idx + 1);
          if (line) onChunk(line);
        }
      }
      onDone && onDone();
    })
    .catch((err) => onError && onError(err));
}

function hasSessionCookie() {
  return document.cookie.split(";").some((c) => c.trim().startsWith("thread_id="));
}

window.api = {
  getHealth,
  getAvailableTimeOptions,
  loginUser,
  trainModel,
  streamChat,
  hasSessionCookie,
};