diff --git a/src/lib/utils/llmChat.js b/src/lib/utils/llmChat.js
new file mode 100644
index 00000000..364f54b9
--- /dev/null
+++ b/src/lib/utils/llmChat.js
@@ -0,0 +1,109 @@
+let fhirResources = null;
+let messages = [];
+
+function initLLMChat(resources) {
+ fhirResources = resources;
+ const llmChatContent = document.getElementById('llm-chat-content');
+ const chatInput = document.getElementById('chat-input');
+ const sendMessageButton = document.getElementById('send-message');
+
+ sendMessageButton.addEventListener('click', sendMessage);
+ chatInput.addEventListener('keypress', (e) => {
+ if (e.key === 'Enter') sendMessage();
+ });
+}
+
+function insertMessageIntoUi(role, userMessage) {
+ const chatMessages = document.getElementById('chat-messages');
+
+ // Create a new table row for the user message
+ const row = document.createElement('tr');
+
+ // Create cells for the request
+ const requestCell = document.createElement('td');
+ requestCell.textContent = userMessage;
+
+ // Create empty cells for response and tokens
+ const responseCell = document.createElement('td');
+ const promptTokensCell = document.createElement('td');
+ const completionTokensCell = document.createElement('td');
+ const costCell = document.createElement('td');
+
+ // Append cells to the row
+ row.appendChild(requestCell);
+ row.appendChild(responseCell);
+ row.appendChild(promptTokensCell);
+ row.appendChild(completionTokensCell);
+ row.appendChild(costCell);
+
+ // Append the row to the chat messages table
+ chatMessages.appendChild(row);
+
+ // Return the row for later updates
+ return row;
+}
+
+// Update the sendMessage function to use the new insertMessageIntoUi
+async function sendMessage() {
+ const chatInput = document.getElementById('chat-input');
+ const userMessage = chatInput.value.trim();
+ if (userMessage.length === 0) return;
+
+ // Append the FHIR resources as the first message
+ if (messages.length === 0) {
+ messages.push({
+ role: "user",
+ content: [{ type: "text", text: JSON.stringify(fhirResources) }]
+ });
+ }
+
+ // Append the user message
+ messages.push({
+ role: "user",
+ content: [{ type: "text", text: userMessage }]
+ });
+
+ // Insert the user message into the UI and get the row reference
+ const row = insertMessageIntoUi('user', userMessage);
+
+ chatInput.value = '';
+
+ try {
+ // FIXME config for this url...
+ const response = await fetch('https://llm-service.fl.mcjustin.dev.cirg.uw.edu/api/chat', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ messages: messages }), // Send the messages array
+ });
+
+ if (!response.ok) {
+ throw new Error('Failed to get LLM response');
+ }
+
+ const data = await response.json();
+ // Append the assistant's response
+ messages.push({
+ role: "assistant",
+ content: [{ type: "text", text: data.content }]
+ });
+
+ const promptTokens = data.prompt_tokens;
+ const completionTokens = data.completion_tokens;
+ const costInput = parseInt(promptTokens) * 0.15 / 1000000;
+ const costOutput = parseInt(completionTokens) * 0.6 / 1000000;
+ const cost = costInput + costOutput;
+
+ // Update the existing row with the response and token counts
+ row.cells[1].textContent = data.content; // Response
+ row.cells[2].textContent = promptTokens; // Prompt Tokens
+ row.cells[3].textContent = completionTokens; // Completion Tokens
+ row.cells[4].textContent = costInput.toString().substring(0,7) + " + " + costOutput.toString().substring(0,7) + " = " + cost.toString().substring(0,7);
+ } catch (error) {
+ console.error('Error sending message to LLM:', error);
+ row.cells[1].textContent = 'Failed to get a response. Please try again.'; // Update response cell with error message
+ }
+}
+
+export { initLLMChat };
diff --git a/src/routes/(viewer)/ips/+page.svelte b/src/routes/(viewer)/ips/+page.svelte
index dcfed60e..5fda9100 100644
--- a/src/routes/(viewer)/ips/+page.svelte
+++ b/src/routes/(viewer)/ips/+page.svelte
@@ -51,9 +51,15 @@
text: {
buttonText: "Generated Text",
dropdownText: "Display text generated by IPS source"
+ },
+ llmchat: {
+ buttonText: "LLM Chat (experimental)",
+ dropdownText: "Chat with a large language model (LLM) about your health"
}
}
+ let showLlmChat = false;
+
let displayModeText:string;
$: {
if ($displayMode) {
@@ -63,6 +69,7 @@
function setMode(mode:string) {
$displayMode = mode;
+ showLlmChat = mode === "llmchat";
}
// End display mode logic
@@ -245,6 +252,27 @@
Your request | +LLM Chat Response | +Prompt Tokens | +Response Tokens | +Cost in US$ (prompt + response = total) | +
---|