Add files via upload
This commit is contained in:
parent
b5ba807c48
commit
bf019c0f77
3 changed files with 135 additions and 149 deletions
5
LICENSE
5
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
The Samuel Public License Revision 5 (SPL-R5)
|
The Sammy Public License Revision 5 Sub-Revision 1 (SPL-R5 SR1)
|
||||||
|
|
||||||
Copyright (c) 2024 Sneed Group
|
Copyright (c) 2024 Sneed Group
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@ In making contributions to the Software, contributors irrevocably assign, transf
|
||||||
|
|
||||||
Furthermore, this document permits the reuse and redistribution of both executable binaries and source code, contingent upon the inclusion of the previously mentioned copyright notice and permission notice in all copies or substantial portions of the Software. It is imperative that you explicitly acknowledge and agree that the owner(s) retain ownership rights over the aforementioned source code.
|
Furthermore, this document permits the reuse and redistribution of both executable binaries and source code, contingent upon the inclusion of the previously mentioned copyright notice and permission notice in all copies or substantial portions of the Software. It is imperative that you explicitly acknowledge and agree that the owner(s) retain ownership rights over the aforementioned source code.
|
||||||
|
|
||||||
Moreover, companies using the Software are encouraged to contribute upstream. Fortune 500 companies are required to make an annual contribution of at least 20,000 USD or an equivalent amount to support the project's sustainability unless no donation option is provided.
|
Moreover, companies using the Software are encouraged to contribute upstream. Fortune 500 companies are required to make an annual contribution of at least 20,000 USD or an equivalent amount per project used to support the said projects' sustainability unless no donation option is provided. Also, all Fortune 500 companies using said projects are required to contibute their changes upstream as well.
|
||||||
|
|
||||||
Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owners(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development.
|
Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owners(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development.
|
||||||
|
|
||||||
In addition, the owner of the code is granted the authority to update their copy of The Samuel Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Samuel Public License.
|
In addition, the owner of the code is granted the authority to update their copy of The Samuel Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Samuel Public License.
|
||||||
|
|
||||||
The aforementioned copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
|
The aforementioned copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
|
180
index.mjs
180
index.mjs
|
@ -1,119 +1,95 @@
|
||||||
import readline from 'readline';
|
import { Ollama } from "@langchain/ollama";
|
||||||
import Ollama from 'ollama-js-client';
|
import { PuppeteerWebBaseLoader } from "@langchain/community/document_loaders/web/puppeteer";
|
||||||
import fs from 'fs';
|
import * as path from 'path'
|
||||||
|
import http from 'http';
|
||||||
|
import { URL } from 'url';
|
||||||
|
const debugMode = false
|
||||||
|
const __dirname = path.resolve();
|
||||||
|
|
||||||
let DEBUG_MODE = true;
|
function llamaLoader(model="sparksammy/samantha-3.1", url="http://localhost:11434") {
|
||||||
|
return new Ollama({
|
||||||
async function ollamaInteraction() {
|
baseUrl: url, // Default value
|
||||||
const rl = await readline.createInterface({
|
model: model, // Default value
|
||||||
input: process.stdin,
|
|
||||||
output: process.stdout,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function isUndefined(value) {
|
|
||||||
if (typeof value == undefined || value == null) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ifUndefinedReturnBlankStr(value) {
|
const ollama = llamaLoader()
|
||||||
if (isUndefined(value)) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ifUndefinedReturnBlankFunction(value) {
|
|
||||||
if (isUndefined(value)) {
|
|
||||||
return Function();
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractFunctionName(response) {
|
|
||||||
const match = response.match(/<functioncall>([^<]+)<\/functioncall>/);
|
|
||||||
return match ? match[1] : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateRandomString(length = 16) {
|
async function loadDoc(www) {
|
||||||
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
try {
|
||||||
let result = "";
|
const loader = new PuppeteerWebBaseLoader(String(www), {
|
||||||
for (let i = 0; i < length; i++) {
|
launchOptions: {
|
||||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
headless: true,
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INTERNAL FUNCTIONS MAGIC BEGIN
|
|
||||||
let internalFunctions = {
|
|
||||||
jitsi: function() {
|
|
||||||
const id = generateRandomString();
|
|
||||||
const jitsiURL = `https://meet.jit.si/${id}`;
|
|
||||||
console.log(jitsiURL);
|
|
||||||
return jitsiURL;
|
|
||||||
},
|
},
|
||||||
search: function(q) {
|
gotoOptions: {
|
||||||
q = q.replaceAll(" ", "+");
|
waitUntil: "domcontentloaded",
|
||||||
const searchURL = `https://www.google.com/search?q=${q}&sca_upv=1`;
|
},
|
||||||
console.log(searchURL);
|
});
|
||||||
return searchURL;
|
|
||||||
|
const docs = await loader.load();
|
||||||
|
return docs[0].pageContent;
|
||||||
|
} catch {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// END OF INTERNAL FUNCTIONS MAGIC
|
|
||||||
|
|
||||||
return new Promise(async (resolve) => {
|
async function getReply(q, www='docChatterThing.testfile.invalid') {
|
||||||
rl.question("User: ", async (userInput) => {
|
let document
|
||||||
rl.close();
|
let query
|
||||||
|
if (www == "docChatterThing.testfile.invalid" || www == "") {
|
||||||
const ollama = new Ollama({
|
document = "Chatting."
|
||||||
model: "sneedgroup-llama3-agent",
|
|
||||||
url: "http://127.0.0.1:11434/api/",
|
|
||||||
}); // Ensure the model name is correct
|
|
||||||
|
|
||||||
const responsePreParse = await ollama.prompt(userInput);
|
|
||||||
const response = responsePreParse.response;
|
|
||||||
const functionName = extractFunctionName(response).replaceAll("\n", '');
|
|
||||||
const responseWithoutFunctionCall = await response.replace(/<functioncall>.*?<\/functioncall>/, '');
|
|
||||||
|
|
||||||
console.log(responseWithoutFunctionCall);
|
|
||||||
|
|
||||||
let contentToAppend = `<USER>: ${userInput}
|
|
||||||
<AI AGENT>: ${responseWithoutFunctionCall}`;
|
|
||||||
|
|
||||||
await fs.appendFile('journal.txt', contentToAppend, async (err) => {
|
|
||||||
if (err) {
|
|
||||||
await console.error(err);
|
|
||||||
} else {
|
} else {
|
||||||
await console.log('Content appended to journal file successfully!');
|
document = await loadDoc(www)
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (DEBUG_MODE) { console.log(`DEBUG: RUN ${functionName}`); }
|
|
||||||
|
|
||||||
// Call the function by name if it exists in internalFunctions
|
|
||||||
try {
|
|
||||||
if (DEBUG_MODE) { console.log(`DEBUG: ${functionName} => internalFunctions[${(functionName)})];`) }
|
|
||||||
internalFunctions[functionName]();
|
|
||||||
console.log("OK")
|
|
||||||
} catch (err) {
|
|
||||||
if (DEBUG_MODE) { console.log(`Error: ${err}`) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(); // Resolve the promise after processing
|
query = String(`Context: ${document} Query: ${q}`)
|
||||||
|
|
||||||
|
if (debugMode) {
|
||||||
|
console.log(query) //Debug feature that prints out the user's query.
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream = await ollama.stream(
|
||||||
|
query
|
||||||
|
);
|
||||||
|
|
||||||
|
const chunks = [];
|
||||||
|
for await (const chunk of stream) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunks.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function main(port) {
|
||||||
|
const hostname = '127.0.0.1';
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
res.statusCode = 200;
|
||||||
|
|
||||||
|
// Create URL object and parse query parameters
|
||||||
|
const urlObj = new URL(req.url, `http://${req.headers.host}`);
|
||||||
|
const queryParams = urlObj.searchParams;
|
||||||
|
|
||||||
|
// Get query parameters with default values if not provided
|
||||||
|
const q = queryParams.get('q') || "Create an error 500 message explaining that the user didn't input a query and optionally a URL.";
|
||||||
|
const www = queryParams.get('www') || "docChatterThing.testfile.invalid";
|
||||||
|
|
||||||
|
// Get reply and send response
|
||||||
|
getReply(q, www).then(answer => {
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.end(String(answer));
|
||||||
|
}).catch(err => {
|
||||||
|
res.statusCode = 500;
|
||||||
|
res.end(`Internal Server Error: ${err.message}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.listen(port, hostname, () => {
|
||||||
|
console.log(`Server running at http://${hostname}:${port}/`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
main(8543)
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
await ollamaInteraction();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error occurred:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
25
package.json
25
package.json
|
@ -1,16 +1,25 @@
|
||||||
{
|
{
|
||||||
"name": "sneedgroup-agent",
|
"dependencies": {
|
||||||
|
"@langchain/community": "^0.2.28",
|
||||||
|
"@langchain/ollama": "^0.0.4",
|
||||||
|
"cheerio": "^1.0.0",
|
||||||
|
"puppeteer": "^23.1.1"
|
||||||
|
},
|
||||||
|
"name": "sneed-agent",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "Sneed Agent",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "Samuel Lord",
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/sneed-group/sneed-agent.git"
|
||||||
|
},
|
||||||
|
"author": "Sneed Group",
|
||||||
"license": "SEE LICENSE IN LICENSE",
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
"dependencies": {
|
"bugs": {
|
||||||
"ollama": "^0.5.0",
|
"url": "https://github.com/sneed-group/sneed-agent/issues"
|
||||||
"ollama-js-client": "^1.0.1",
|
},
|
||||||
"readline": "^1.3.0"
|
"homepage": "https://github.com/sneed-group/sneed-agent#readme"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue