diff --git a/examples/server/public/completion.js b/examples/server/public/completion.js index 81c664520..54a0f22f5 100644 --- a/examples/server/public/completion.js +++ b/examples/server/public/completion.js @@ -5,6 +5,12 @@ const paramDefaults = { let generation_settings = null; +export class CompletionError extends Error { + constructor(message, name, data) { + super(message); + this.name = name; + } +}; // Completes the prompt as a generator. Recommended for most use cases. // @@ -39,6 +45,18 @@ export async function* llama(prompt, params = {}, config = {}) { signal: controller.signal, }); + const status = response.status; + if (status !== 200) { + try { + const body = await response.json(); + if (body && body.error && body.error.message) { + throw new CompletionError(body.error.message, 'ServerError'); + } + } catch (err) { + throw new CompletionError(err.message, 'ServerError'); + } + } + const reader = response.body.getReader(); const decoder = new TextDecoder(); diff --git a/examples/server/public/index.html b/examples/server/public/index.html index 58a896591..f768d316f 100644 --- a/examples/server/public/index.html +++ b/examples/server/public/index.html @@ -285,6 +285,14 @@ conv.lastModified = Date.now(); localStorage.setItem(convId, JSON.stringify(conv)); }, + popMsg(convId) { + const conv = StorageUtils.getOneConversation(convId); + if (!conv) return; + const msg = conv.messages.pop(); + conv.lastModified = Date.now(); + localStorage.setItem(convId, JSON.stringify(conv)); + return msg; + }, // manage config getConfig() { @@ -425,6 +433,7 @@ top_p: this.config.top_p, max_tokens: this.config.max_tokens, ...(this.config.custom.length ? JSON.parse(this.config.custom) : {}), + ...(this.config.apiKey ? { api_key: this.config.apiKey } : {}), }; const config = { controller: abortController, @@ -457,13 +466,16 @@ } else { console.error(error); alert(error); - this.inputMsg = this.pendingMsg.content || ''; + // pop last user message + const lastUserMsg = StorageUtils.popMsg(currConvId); + this.inputMsg = lastUserMsg ? lastUserMsg.content : ''; } } this.pendingMsg = null; this.isGenerating = false; this.stopGeneration = () => {}; + this.fetchMessages(); }, // message actions diff --git a/examples/server/server.cpp b/examples/server/server.cpp index 5ece0473e..7f6fc65b7 100644 --- a/examples/server/server.cpp +++ b/examples/server/server.cpp @@ -2356,6 +2356,11 @@ int main(int argc, char ** argv) { "/v1/models", }; + // If this is OPTIONS request, skip validation because browsers don't include Authorization header + if (req.method == "OPTIONS") { + return true; + } + // If API key is not set, skip validation if (params.api_keys.empty()) { return true;