Following the fourth article, since I didn't know what to write, I happened to see someone in the group mention how to call the anythingllm API elsewhere, which led to this blog post, intended for technical learning purposes. For more application methods, please refer to the anythingllm API documentation.
Now that we have built a knowledge base using the private knowledge base set up with cloud studio, how can we call it elsewhere, or can we provide an API for our use?
anythingllm actually provides an API, but you need to have a bit of programming knowledge to use it. After all, having an API means we can use it under any project, as the data we feed in needs to be utilized, and we want to use it wherever we want, not just under anythingllm.
Alright, without further ado, let's start the tutorial.
Now that we have fed data to deepseek through the fourth article, how can we use it via the API?
- Open the anythingllm settings interface [wrench icon].
- Scroll through the left menu and select Tools ---> API Key
- Click to generate a new API key, a new pop-up will appear, we create the API key.
- Then click copy key and read the API doc in sequence,
- On the opened AnythingLLM Developer API page, we click
Authorize
, paste the API key we just copied.
- Close the pop-up.
- Scroll down to find /v1/workspace/{slug}/stream-chat under the Workspaces group and click it.
- Click the try out button and modify the slug value, the slug value is the name of the workspace we created initially.
See the image: Workspace
My value here is demo.
And modify the Request body content to:
{
"message": "Hello, what large model are you?",
"mode": "chat"
}
Finally, click execute.
As shown in the image:
After a moment, we will see the response content.
Here, we are testing whether this API can be used normally.
So how can we call it elsewhere?
Suppose we call it from a webpage.
This requires using node + html.
Since this is a test, I will directly provide my demo code.
main.js
document.addEventListener('DOMContentLoaded', () => {
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const stopButton = document.getElementById('stop-button');
const chatMessages = document.getElementById('chat-messages');
const authInput = document.getElementById('auth-input');
const saveAuthButton = document.getElementById('save-auth-button');
let currentController = null;
function addMessage(message, isUser = false) {
const messageElement = document.createElement('div');
messageElement.classList.add('message');
messageElement.classList.add(isUser ? 'user-message' : 'bot-message');
messageElement.textContent = message;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
function setLoading(isLoading) {
sendButton.disabled = isLoading;
messageInput.disabled = isLoading;
stopButton.disabled = !isLoading;
sendButton.textContent = isLoading ? 'Sending...' : 'Send';
}
async function typeText(element, text) {
const delay = 20; // Delay time for each character (milliseconds)
for (let i = 0; i < text.length; i++) {
const char = text[i];
const span = document.createElement('span');
span.textContent = char;
span.classList.add('typing');
element.appendChild(span);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
async function sendMessage(message) {
try {
setLoading(true);
currentController = new AbortController();
const response = await fetch('https://ottzkl-pkzulq-3001.app.cloudstudio.work/api/v1/workspace/demo/stream-chat', {
method: 'POST',
headers: {
'accept': 'text/event-stream',
'Authorization': `Bearer ${authInput.value}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: message,
mode: 'chat'
}),
signal: currentController.signal
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let currentMessageElement = null;
let buffer = '';
while (true) {
const {value, done} = await reader.read();
if (done) break;
const chunk = decoder.decode(value, {stream: true});
buffer += chunk;
let startIndex = 0;
while (true) {
const endIndex = buffer.indexOf('\n', startIndex);
if (endIndex === -1) break;
const line = buffer.slice(startIndex, endIndex).trim();
startIndex = endIndex + 1;
if (line.startsWith('data:')) {
try {
const jsonStr = line.substring(5).trim();
if (!jsonStr) continue;
const data = JSON.parse(jsonStr);
if (data.textResponse !== undefined) {
if (!currentMessageElement) {
currentMessageElement = document.createElement('div');
currentMessageElement.classList.add('message', 'bot-message');
chatMessages.appendChild(currentMessageElement);
}
await typeText(currentMessageElement, data.textResponse);
chatMessages.scrollTop = chatMessages.scrollHeight;
} else if (data.error) {
throw new Error(data.error);
}
} catch (e) {
console.error('Error parsing response data:', e);
}
}
}
buffer = buffer.slice(startIndex);
}
} catch (error) {
if (error.name === 'AbortError') {
addMessage('Conversation stopped', false);
} else {
console.error('Error:', error);
let errorMessage = 'Sorry, an error occurred';
if (error.response) {
errorMessage += ` (HTTP ${error.response.status})`;
} else if (error.request) {
errorMessage += ' (Network connection failed)';
} else {
errorMessage += ` (${error.message})`;
}
addMessage(errorMessage, false);
}
} finally {
currentController = null;
setLoading(false);
}
}
stopButton.addEventListener('click', () => {
if (currentController) {
currentController.abort();
}
});
saveAuthButton.addEventListener('click', () => {
const authValue = authInput.value.trim();
if (authValue) {
addMessage('Authorization code updated', false);
} else {
addMessage('Please enter a valid authorization code', false);
}
});
sendButton.addEventListener('click', () => {
const message = messageInput.value.trim();
if (message) {
addMessage(message, true);
messageInput.value = '';
sendMessage(message);
}
});
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendButton.click();
}
});
// Add welcome message
addMessage('Hello! I am the AI assistant, how can I help you?', false);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AnythingLLM Chat</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.chat-container {
max-width: 800px;
margin: 0 auto;
background-color: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
height: 90vh;
}
.settings-container {
padding: 10px 20px;
border-bottom: 1px solid #dee2e6;
display: flex;
gap: 10px;
align-items: center;
}
.auth-input {
flex-grow: 1;
padding: 8px;
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 14px;
}
.save-auth-button {
padding: 8px 15px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
}
.save-auth-button:hover {
background-color: #218838;
}
.chat-messages {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 15px;
max-width: 70%;
animation: fadeIn 0.3s ease-in-out;
word-wrap: break-word;
}
.user-message {
background-color: #007bff;
color: white;
margin-left: auto;
}
.bot-message {
background-color: #e9ecef;
color: black;
margin-right: auto;
}
.typing {
display: inline-block;
overflow: hidden;
white-space: pre-wrap;
animation: typing 0.05s steps(1, end);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.input-container {
padding: 20px;
border-top: 1px solid #dee2e6;
display: flex;
gap: 10px;
}
#message-input {
flex-grow: 1;
padding: 10px;
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 16px;
}
.action-button {
padding: 10px 20px;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
#send-button {
background-color: #007bff;
}
#stop-button {
background-color: #dc3545;
}
#send-button:hover {
background-color: #0056b3;
}
#stop-button:hover {
background-color: #c82333;
}
#stop-button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="chat-container">
<div class="settings-container">
<input type="text" id="auth-input" class="auth-input" placeholder="Enter authorization code..." value="E8HX1PF-BWT4ZZM-KW8VGRH-9W0QS1B" />
<button id="save-auth-button" class="save-auth-button">Save Authorization Code</button>
</div>
<div class="chat-messages" id="chat-messages"></div>
<div class="input-container">
<input type="text" id="message-input" placeholder="Enter message..." />
<button id="send-button" class="action-button">Send</button>
<button id="stop-button" class="action-button" disabled>Stop</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>
These two files can be directly written in cs.
The directory structure is as follows:
Then in the terminal, run, I simply use python to provide the web service on port 8089, press enter, nginx or nodejs can also be used.
python3 -m http.server 8089
Click to open the browser.
Paste the key we created earlier and click save.
Enter our question in the dialog box.
Let's see how the response is.
At this point, we have already called the data from our private knowledge base in the demo workspace.