From 5be5fd1e857877f6f5f6d93c32dc3873bfc61699 Mon Sep 17 00:00:00 2001 From: Calvin Secrest Date: Fri, 5 Sep 2025 20:55:51 -0400 Subject: [PATCH 1/2] Add api.stream helper and switch ChatWindow to use it --- frontend/chat-ui/src/api.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/frontend/chat-ui/src/api.js b/frontend/chat-ui/src/api.js index 4c6bf67..7466653 100644 --- a/frontend/chat-ui/src/api.js +++ b/frontend/chat-ui/src/api.js @@ -1,22 +1,30 @@ export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || ''; const API_KEY = import.meta.env.VITE_API_KEY || ''; +function buildUrl(path) { + const clean = path.startsWith('/') ? path : `/${path}`; + return API_BASE_URL ? `${API_BASE_URL.replace(/\/$/, '')}${clean}` : clean; +} + async function request(method, path, body) { - const headers = { 'x-api-key': API_KEY }; + const url = buildUrl(path); + const headers = {}; + if (API_KEY) headers['x-api-key'] = API_KEY; const options = { method, headers }; if (body !== undefined) { headers['Content-Type'] = 'application/json'; options.body = JSON.stringify(body); } - const res = await fetch(`${API_BASE_URL}${path}`, options); + const res = await fetch(url, options); const text = await res.text(); let data = null; if (text) { try { data = JSON.parse(text); } catch (err) { - throw err; + // non-JSON response; preserve text in data + data = text; } } if (!res.ok) { @@ -33,4 +41,15 @@ export const post = (path, body) => request('POST', path, body); export const put = (path, body) => request('PUT', path, body); export const del = (path) => request('DELETE', path); -export default { get, post, put, del }; +// Create an EventSource for SSE. If the server does not accept headers for SSE, +// the API key will be appended as a query parameter named `x-api-key`. +export function stream(path) { + let url = buildUrl(path); + if (API_KEY) { + const hasQuery = url.includes('?'); + url = `${url}${hasQuery ? '&' : '?'}x-api-key=${encodeURIComponent(API_KEY)}`; + } + return new EventSource(url); +} + +export default { get, post, put, del, stream; \ No newline at end of file From 74fa8b16f3848a66bbd5cffb72411c5987ca3cdd Mon Sep 17 00:00:00 2001 From: Calvin Secrest Date: Fri, 5 Sep 2025 20:59:41 -0400 Subject: [PATCH 2/2] Add api.stream helper and switch ChatWindow to use it --- frontend/chat-ui/src/api.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/chat-ui/src/api.js b/frontend/chat-ui/src/api.js index 7466653..12e2293 100644 --- a/frontend/chat-ui/src/api.js +++ b/frontend/chat-ui/src/api.js @@ -41,8 +41,8 @@ export const post = (path, body) => request('POST', path, body); export const put = (path, body) => request('PUT', path, body); export const del = (path) => request('DELETE', path); -// Create an EventSource for SSE. If the server does not accept headers for SSE, -// the API key will be appended as a query parameter named `x-api-key`. +// Create an EventSource for SSE. Many servers don't accept custom headers for SSE, +// so we append the API key as a query parameter named `x-api-key` when present. export function stream(path) { let url = buildUrl(path); if (API_KEY) { @@ -52,4 +52,4 @@ export function stream(path) { return new EventSource(url); } -export default { get, post, put, del, stream; \ No newline at end of file +export default { get, post, put, del, stream }; \ No newline at end of file