pediatric-ai-scribe-v3/public/js/assistant/api.js

139 lines
4.8 KiB
JavaScript

function authHeaders() {
var token = typeof localStorage === 'undefined' ? null : localStorage.getItem('auth_token');
return token ? { Authorization: 'Bearer ' + token } : {};
}
function parseJsonWithStatus(response) {
return response.json().catch(function () { return {}; }).then(function(data) {
data._status = response.status;
return data;
});
}
export function fetchAssistantStatus() {
return fetch('/api/clinical-assistant/status', { headers: authHeaders(), credentials: 'same-origin' })
.then(function(r) { return r.json(); });
}
export function fetchAssistantExamples() {
return fetch('/api/clinical-assistant/examples', { headers: authHeaders(), credentials: 'same-origin' })
.then(function(r) { return r.json(); });
}
export function openAssistantStream(payload, options) {
options = options || {};
return fetch('/api/clinical-assistant/chat/stream', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
signal: options.signal,
body: JSON.stringify(payload)
});
}
export function fetchAssistantChat(payload, options) {
options = options || {};
return fetch('/api/clinical-assistant/chat', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
signal: options.signal,
body: JSON.stringify(payload)
}).then(parseJsonWithStatus);
}
export function requestAssistantImage(prompt) {
return fetch('/api/clinical-assistant/image', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
body: JSON.stringify({ prompt: prompt })
}).then(function(r) { return r.json(); });
}
export function translateAssistantMessage(message, target, provider) {
return fetch('/api/clinical-assistant/translate', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
body: JSON.stringify({ message: message, target: target, provider: provider })
}).then(parseJsonWithStatus);
}
var imageDraft = null;
export function startAssistantImageJob(prompt, history) {
const input = { prompt, ...(history === undefined ? {} : { history }) };
const identity = JSON.stringify(input);
if (!imageDraft || imageDraft.identity !== identity) imageDraft = { identity, body: { ...input, idempotencyKey: crypto.randomUUID() } };
return fetch('/api/clinical-assistant/image/jobs', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
body: JSON.stringify(imageDraft.body)
}).then(function(r) { return r.json(); });
}
export function fetchAssistantImageJob(jobId) {
return fetch('/api/clinical-assistant/image/jobs/' + encodeURIComponent(jobId), {
headers: authHeaders(),
credentials: 'same-origin'
}).then(function(r) { return r.json(); });
}
export function saveAssistantChat(payload) {
return fetch('/api/clinical-assistant/chats', {
method: 'POST',
headers: authHeaders(),
credentials: 'same-origin',
body: JSON.stringify(payload)
}).then(parseJsonWithStatus);
}
export function fetchSavedAssistantChats() {
return fetch('/api/clinical-assistant/chats', { headers: authHeaders(), credentials: 'same-origin' })
.then(function(r) { return r.json(); });
}
export function fetchSavedAssistantChat(id) {
return fetch('/api/clinical-assistant/chats/' + encodeURIComponent(id), { headers: authHeaders(), credentials: 'same-origin' })
.then(parseJsonWithStatus);
}
export function deleteSavedAssistantChat(id) {
return fetch('/api/clinical-assistant/chats/' + encodeURIComponent(id), {
method: 'DELETE',
headers: authHeaders(),
credentials: 'same-origin'
}).then(function(r) { return r.json(); });
}
// Image attachments ride the outgoing clinical question payload for inference.
// Once a question is sent, its attachments persist with the saved chat. The
// server enforces the same limits authoritatively; these mirror them for early
// feedback.
export var assistantAttachmentLimits = Object.freeze({
mimeTypes: ['image/png', 'image/jpeg', 'image/webp'],
maxImages: 4,
maxImageBytes: 5 * 1024 * 1024,
maxTotalBytes: 10 * 1024 * 1024
});
export function assistantAttachmentPayload(attachments) {
return (Array.isArray(attachments) ? attachments : []).map(function(attachment) {
return { dataBase64: attachment.dataBase64, mimeType: attachment.mimeType };
});
}
export function fetchAssistantImageJobs() {
return fetch('/api/clinical-assistant/image/jobs?limit=24', { headers: authHeaders(), credentials: 'same-origin' })
.then(parseJsonWithStatus);
}
export function renameSavedAssistantChat(id, title) {
return fetch('/api/clinical-assistant/chats/' + encodeURIComponent(id), {
method: 'PATCH',
headers: authHeaders(Object.assign({ 'Content-Type': 'application/json' })),
credentials: 'same-origin',
body: JSON.stringify({ title: title })
}).then(parseJsonWithStatus);
}