Merge 89d4bf86c7dd33d0c4bd39a9e49e7a3fe1d604e0 into d7eb05b9361febead29a74e71ddffc2ebeff5302
This commit is contained in:
commit
1e670eafff
62
examples/simple-webclient/README.md
Normal file
62
examples/simple-webclient/README.md
Normal file
@ -0,0 +1,62 @@
|
||||
# a really really simple web client
|
||||
|
||||
This is a web Client with almost NO features but a small starting point for
|
||||
people who want to try for themselves.
|
||||
It utilizes a simple XmlHttpRequest and prints the output to screen.
|
||||
|
||||
I also implemented the use of marked for highlighting the chat.
|
||||
|
||||
Since there is no on-the-fly-reception, getting an answer may take a while...
|
||||
|
||||
# usage
|
||||
|
||||
## using it locally
|
||||
|
||||
if you just want to try, run firefox in your command line like this:
|
||||
|
||||
```
|
||||
$ firefox file:///path/to/ollama/examples/simple-webclient/webcli.html?host=your_hostname
|
||||
```
|
||||
|
||||
This opens your browser (eg firefox) and in this case, directly sets ollama host to
|
||||
_http://your_hostname:11434_.
|
||||
Default host is either the host where the script runs or just `localhost`.
|
||||
|
||||
For more configuration, see `Configuring`
|
||||
|
||||
## using behind nginx
|
||||
|
||||
The most comfortable way I found was using the cli on nginx.
|
||||
|
||||
! This is only an example. You should use a dedicated site in nginx !
|
||||
|
||||
Therefore, I just copied webcli.html to /var/www/html/.
|
||||
|
||||
To make it run, you might need to edit the location in `/etc/nginx/sites-available/default`
|
||||
and add
|
||||
|
||||
```
|
||||
...
|
||||
location / {
|
||||
...
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
...
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
After that, you need to reload nginx.
|
||||
|
||||
Now, you should be able to access webcli via `http://your_host/webcli.html`
|
||||
|
||||
|
||||
## Configuring
|
||||
|
||||
If you want to configure a bit more, just click the "Configure" link below your chat input.
|
||||
A form opens and you can input hostname, port, whether using https, as well as the used
|
||||
model, parameters and system input.
|
||||
|
||||
# Todo
|
||||
|
||||
Well, there's still something to do here. Source code formatting would be cool or maybe
|
||||
saving the configuration somehow.. Feel free..
|
193
examples/simple-webclient/webcli.html
Normal file
193
examples/simple-webclient/webcli.html
Normal file
@ -0,0 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>My<CR>Ollama</title>
|
||||
<style>
|
||||
// first, format the input and output divs
|
||||
#outputdiv {
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0.5em;
|
||||
border-radius: 0.5em 0.5em 0 0;
|
||||
background-color: #f9f9fb;
|
||||
left: 1em;
|
||||
right: 1em;
|
||||
//width: calc(100% - 1em);
|
||||
border: 1px solid;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0.5em;
|
||||
border-radius: 0 0 0.5em 0.5em;
|
||||
background-color: #ffffff;
|
||||
left: 1em;
|
||||
right: 1em;
|
||||
//width: calc(100% - 1em);
|
||||
border: 1px solid;
|
||||
border-color: #ccc;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#inputdiv {
|
||||
border-radius: 0.5em 0.5em 0.5em 0.5em;
|
||||
bottom: 1em;
|
||||
left: 1em;
|
||||
right: 1em;
|
||||
padding: 1em;
|
||||
font-size: 16px;
|
||||
border:1px solid #ccc;
|
||||
background-color: #ebebf9;
|
||||
}
|
||||
|
||||
#inputdiv input[type="text"] {
|
||||
width:20em;
|
||||
}
|
||||
|
||||
#inputdiv label {
|
||||
display:inline-block;
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
pre {
|
||||
left: 1em;
|
||||
right: 1em;
|
||||
padding: 1em;
|
||||
font-size: 16px;
|
||||
border:1px solid #ccc;
|
||||
background-color: #f0f0fc;
|
||||
}
|
||||
|
||||
// todo: format marked
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<div id="outputdiv"></div>
|
||||
<div id="inputdiv">
|
||||
<form id="inputform" onsubmit="send_form(event)">
|
||||
<textarea id="textfield" name="text" style="width:calc(100% - 8em);height:5em;"></textarea>
|
||||
<input type="submit" value="Senden" id="sendenButton" style>
|
||||
<hr/>
|
||||
<a onclick="toggle_visibility('config')">Configure</a>
|
||||
<div id="config" style="display:none">
|
||||
<label for="hostname">Hostname</label> <input type="text" id="hostname" value=""/><br>
|
||||
<label for="port">Port</label> <input type="text" id="port" value=""/><br>
|
||||
<label for="https">HTTPS</label> <input type="checkbox" id="https" /><br>
|
||||
<label for="model">Model</label> <input type="text" id="model" value=""/><br>
|
||||
<label for="parameters">Parameters</label><textarea id="parameters">{"stream":false}</textarea><br>
|
||||
<label for="system">System</label><textarea id="system"></textarea><br>
|
||||
<input type="hidden" id="context" value="[]" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const ollama_host=searchParams.get("host") || new URL(window.location.href).hostname || "localhost";
|
||||
const ollama_port=searchParams.get("port") || "11434";
|
||||
const ollama_https=searchParams.get("https") || null;
|
||||
const ollama_model=searchParams.get("model") || "llama3.1";
|
||||
|
||||
document.getElementById("hostname").value=ollama_host;
|
||||
document.getElementById("port").value=ollama_port;
|
||||
document.getElementById("https").checked=ollama_https;
|
||||
document.getElementById("model").value=ollama_model;
|
||||
|
||||
document.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Enter' && ! event.shiftKey) {
|
||||
send_form(event);
|
||||
}}
|
||||
);
|
||||
|
||||
function toggle_visibility(field) {
|
||||
item = document.getElementById(field);
|
||||
item.style.display = (item.style.display == "block") ? "none" : "block";
|
||||
}
|
||||
|
||||
function append_question(text) {
|
||||
parent = document.getElementById("outputdiv");
|
||||
header = document.createElement("div");
|
||||
header.classList.add("header");
|
||||
header.innerText="You said";
|
||||
|
||||
data = document.createElement("div");
|
||||
data.classList.add("content");
|
||||
data.innerHTML = marked.parse(text);
|
||||
parent.appendChild(header);
|
||||
parent.appendChild(data);
|
||||
|
||||
document.getElementById("inputdiv").scrollIntoView();
|
||||
}
|
||||
|
||||
function append_text(text) {
|
||||
parent = document.getElementById("outputdiv");
|
||||
header = document.createElement("div");
|
||||
header.classList.add("header");
|
||||
|
||||
data = document.createElement("div");
|
||||
data.classList.add("content");
|
||||
data.innerHTML = marked.parse(text);
|
||||
|
||||
hd = document.createElement("input");
|
||||
hd.type = "hidden";
|
||||
hd.textContent = text;
|
||||
copy = document.createElement("button");
|
||||
copy.textContent = "Copy";
|
||||
copy.addEventListener('click', () => {
|
||||
const textinhalt = hd.textContent;
|
||||
navigator.clipboard.writeText(textinhalt);
|
||||
});
|
||||
|
||||
parent.appendChild(header);
|
||||
header.appendChild(copy);
|
||||
header.appendChild(hd);
|
||||
parent.appendChild(data);
|
||||
|
||||
document.getElementById("inputdiv").scrollIntoView();
|
||||
}
|
||||
|
||||
function send_form(event) {
|
||||
event.preventDefault();
|
||||
const data = JSON.parse(document.getElementById("parameters").value) || {};
|
||||
data.prompt = document.getElementById("textfield").value;
|
||||
document.getElementById("textfield").value = "";
|
||||
data.system = document.getElementById("system").value;
|
||||
data.model = document.getElementById("model").value;
|
||||
let ctx = document.getElementById("context").value;
|
||||
data.context = JSON.parse(ctx);
|
||||
|
||||
append_question(data.prompt);
|
||||
|
||||
// remove the context
|
||||
if (data.prompt == "/clear") {
|
||||
document.getElementById("context").value = "[]";
|
||||
append_text("Context has been cleared.");
|
||||
return;
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
let url = (ollama_https == null) ? "http://" : "https://";
|
||||
url += ollama_host + ":" + ollama_port +"/api/generate";
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
|
||||
xhr.setRequestHeader('Content-type', 'application/json');
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {
|
||||
resp = JSON.parse(xhr.responseText);
|
||||
document.getElementById("context").value = JSON.stringify(resp.context);
|
||||
append_text(resp.response);
|
||||
|
||||
} else {
|
||||
console.error(xhr.statusText);
|
||||
}
|
||||
};
|
||||
xhr.send(JSON.stringify(data));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user